package com.zy.openchat.core.manager;
import android.app.Application;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.util.Pair;

import com.blankj.utilcode.util.LogUtils;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Reader;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.ja.openchat.R;
import com.zy.openchat.core.model.circle.TextEntities;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.amap.api.location.AMapLocation;
import com.amap.api.services.core.PoiItem;
import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.github.promeg.pinyinhelper.Pinyin;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.ja.openchat.BuildConfig;
import com.ja.openchat.data.NotShowPoiItem;
import com.ja.openchat.ui.OuterShareActivity;
import com.ja.openchat.ui.me.SettingManager;
import com.lqr.emoji.StickerManager;
import com.zy.openchat.App;
import com.zy.openchat.Constants;
import com.zy.openchat.core.model.call.CallBaseInfo;
import com.zy.openchat.core.model.call.CallManager;
import com.zy.openchat.core.model.call.RemoteCallInfo;
import com.zy.openchat.core.model.circle.BlogInfo;
import com.zy.openchat.core.model.circle.BlogLikeInfo;
import com.zy.openchat.core.model.circle.BlogListInfo;
import com.zy.openchat.core.model.circle.BlogPrivacyInfo;
import com.zy.openchat.core.model.circle.BlogReplyInfo;
import com.zy.openchat.core.model.circle.BlogReplysInfo;
import com.zy.openchat.core.model.circle.BlogTopics;
import com.zy.openchat.core.model.circle.BlogUnreadsInfo;
import com.zy.openchat.core.model.circle.BlogUserInfo;
import com.zy.openchat.core.model.circle.CircleTopicInfo;
import com.zy.openchat.core.model.circle.CircleVisibleType;
import com.zy.openchat.core.model.circle.InputBlogIdType;
import com.zy.openchat.core.model.circle.MediaInfo;
import com.zy.openchat.core.model.circle.SubmitWrapperFileInfo;
import com.zy.openchat.core.model.circle.UserTagListInfo;
import com.zy.openchat.core.model.circle.UserTags;
import com.zy.openchat.core.model.circle.VisibleTypeInfo;
import com.zy.openchat.core.model.config.AppConfigInfo;
import com.zy.openchat.core.model.config.TabExMenuInfo;
import com.zy.openchat.core.model.contact.ChatsInfo;
import com.zy.openchat.core.model.contact.UpdateChatActionInfo;
import com.zy.openchat.core.model.discover.ChatsNearbyInfo;
import com.zy.openchat.core.model.discover.DiscoverMenuSectionInfo;
import com.zy.openchat.core.model.file.FileInfo;
import com.zy.openchat.core.model.file.FileTaskInfo;
import com.zy.openchat.core.model.group.BasicGroupFullInfo;
import com.zy.openchat.core.model.group.BasicGroupInfo;
import com.zy.openchat.core.model.group.ChatInviteLink;
import com.zy.openchat.core.model.group.ChatOnlineMemberCountInfo;
import com.zy.openchat.core.model.group.GroupManagePermissionInfo;
import com.zy.openchat.core.model.group.GroupMemberInfo;
import com.zy.openchat.core.model.group.GroupUserInfo;
import com.zy.openchat.core.model.group.RequestData;
import com.zy.openchat.core.model.group.SuperGroupFullInfo;
import com.zy.openchat.core.model.group.SuperGroupInfo;
import com.zy.openchat.core.model.message.BurnAfterReadInfo;
import com.zy.openchat.core.model.message.BurnAfterWrappter;
import com.zy.openchat.core.model.message.ChatInfo;
import com.zy.openchat.core.model.message.ChatPermissions;
import com.zy.openchat.core.model.message.DeleteMessagesInfo;
import com.zy.openchat.core.model.message.FormatTextInfo;
import com.zy.openchat.core.model.message.HtmlDocumentInfo;
import com.zy.openchat.core.model.message.InlineKeyboardButton;
import com.zy.openchat.core.model.message.MessageInfo;
import com.zy.openchat.core.model.message.MessageReaction;
import com.zy.openchat.core.model.message.MessageReactionInfo;
import com.zy.openchat.core.model.message.MessageSendUser;
import com.zy.openchat.core.model.message.PinMessage;
import com.zy.openchat.core.model.message.ReplyMarkupInfo;
import com.zy.openchat.core.model.message.SearchMessagesFilter;
import com.zy.openchat.core.model.message.SecretChatInfo;
import com.zy.openchat.core.model.message.TextEntity;
import com.zy.openchat.core.model.photo.ProfilePhoto;
import com.zy.openchat.core.model.redpacket.RedPacketInfo;
import com.zy.openchat.core.model.redpacket.RedPacketPickUser;
import com.zy.openchat.core.model.remittance.RemittanceDetailInfo;
import com.zy.openchat.core.model.remittance.RemittanceInfo;
import com.zy.openchat.core.model.setting.AccountTtlInfo;
import com.zy.openchat.core.model.setting.NotificationSettingsInfo;
import com.zy.openchat.core.model.setting.UserPrivacySetting;
import com.zy.openchat.core.model.setting.UserPrivacySettingInfo;
import com.zy.openchat.core.model.setting.UserPrivacySettingRules;
import com.zy.openchat.core.model.sticker.StickerInfo;
import com.zy.openchat.core.model.user.MobileContactInfo;
import com.zy.openchat.core.model.user.OrgUserInfo;
import com.zy.openchat.core.model.user.TotalSessionsInfo;
import com.zy.openchat.core.model.user.UserFullInfo;
import com.zy.openchat.core.model.user.UserInfo;
import com.zy.openchat.core.model.user.UserMyInfo;
import com.zy.openchat.core.model.user.UserStatus;
import com.zy.openchat.core.model.version.AppVersionInfo;
import com.zy.openchat.core.model.wallet.ThirdRechargeChannelInfo;
import com.zy.openchat.core.model.wallet.WalletInfo;
import com.zy.openchat.core.model.wallet.WalletOrderInfo;
import com.zy.openchat.core.model.wallet.WalletRechargeRes;
import com.zy.openchat.core.model.wallet.WalletTixianRes;
import com.zy.openchat.util.Common;
import com.zy.openchat.util.ContactUtils;
import com.zy.openchat.util.LocalNotificationHelper;
import com.zy.openchat.util.LocationHelper;
import com.zy.openchat.util.System;

import org.apache.commons.lang3.StringUtils;
import org.drinkless.tdlib.JsonClient;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.jpush.android.api.JPushInterface;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import android.graphics.Bitmap;
public class TelegramManager {
    // <editor-fold defaultstate="collapsed" desc="常量定义">
    //用户状态
    public enum GoUserState {
        GoUserState_Unkown,
        GoUserState_TdlibParameters,
        GoUserState_WaitEncryptionKey,
        GoUserState_WaitPhoneNumber,
        GoUserState_WaitCode,
        GoUserState_WaitRegistration,
        GoUserState_WaitPassword,
        GoUserState_Ready,
        GoUserState_Ready_Background,
        GoUserState_Closed,
        GoUserState_Closing,
        GoUserState_LoggingOut,
        GoUserState_WaitOtherDeviceConfirmation,
    }

    //连接状态
    public enum GoUserConnectionState {
        GoUserConnectionState_Connecting,
        GoUserConnectionState_Updating,
        GoUserConnectionState_StateReady,
    }

    //成员状态
    public enum GroupMemberState {
        GroupMemberState_Administrator,
        GroupMemberState_Creator,
        GroupMemberState_Left,
        GroupMemberState_Member,
        GroupMemberState_Banned,
        GroupMemberState_Restricted,
    }

    //消息类型
    public enum MessageType {
        MessageType_Unkown,
        MessageType_Text, //文本消息
        MessageType_Text_AudioAVideo_Done,//在线音视频消息
        MessageType_Text_New_Rp,    //新红包
        MessageType_Text_Got_Rp,    //红包领取
        MessageType_Animation, //
        MessageType_Audio,  //语音消息
        MessageType_Document, //文件消息
        MessageType_Photo, //图片消息
        MessageType_Sticker,
        MessageType_Video, //视频消息
        MessageType_Poll,
        MessageType_Location,
        MessageType_Call,
        MessageType_Pinned, //群组公告
        MessageType_Text_Screenshot, //截屏消息
        MessageType_Text_BeFriend, //加好友消息
        MessageType_Contact,
        MessageType_Text_New_Tm,    //新转账
        MessageType_Text_Got_Tm,  //转账领取
        MessageType_Text_Refund_Tm,   //转账退还
        MessageType_Contact_Registered,
        MessageType_Group_Kick,//被踢出群
        MessageType_Voice_Note,  //PC语音消息

    }

    //消息发送状态
    public enum MessageSendState {
        MessageSendState_Success,
        MessageSendState_Pending,
        MessageSendState_Fail,
    }

    //文件类型定义
    public enum FileType {
        //联系人头像
        FileType_Photo,
        //群组头像
        FileType_Group_Photo,
        //消息图片
        FileType_Message_Photo,
        //消息预览图片
        FileType_Message_Preview_Photo,
        //消息视频
        FileType_Message_Video,
        //消息语音
        FileType_Message_Audio,
        //消息语音
        FileType_Message_Voice,
        //消息文件
        FileType_Message_Document,
        FileType_Message_Animation,
    }

    //扩展消息定义
    //音视频通话消息
    public static final int AudioAVideo_MessageType = 1;
    //通话已结束
    public static final int AudioAVideo_MessageType_Done = 100;

    //阅后即焚
    public static final int BurnAfterRead_MessageType = 4;
    //阅后即焚
    public static final int BurnAfterRead_MessageType_Done = 100;

    //红包消息
    public static final int RP_MessageType = 2;
    //新红包消息
    public static final int RP_MessageType_New = 100;
    //红包领取消息
    public static final int RP_MessageType_Got = 200;

    //转账消息
    public static final int TM_MessageType = 5;
    //新转账消息
    public static final int TM_MessageType_New = 100;
    //转账领取消息
    public static final int TM_MessageType_Got = 200;
    //转账用户退款消息
    public static final int TM_MessageType_Refund = 300;
    //提醒转账消息
    public static final int TM_MessageType_Remind = 400;
    //转账系统退款消息
    public static final int TM_MessageType_Refund_By_System = 500;

    //其它扩展类消息
    public static final int OtherEx_MessageType = 3;
    //截屏消息
    public static final int OtherEx_MessageType_Screenshot = 100;
    //加好友消息
    public static final int OtherEx_MessageType_BeFriend = 101;

    //群聊关键词
    public static final int Group_Keyword_MessageType = 6;
    public static final int Group_Keyword_MessageType_KICK = 100;

    //红包状态定义
    public enum RpState {
        RpState_Expire, //已过期
        RpState_To_Get,     //未领取，待抢
        RpState_Got,        //已领取
        RpState_GotADone,   //已领取并且被抢光
        RpState_Done,       //已被抢光
    }

    //短信验证码类型
    public enum SmsCodeType {
        SmsCodeType_SetWalletPassword, //修改钱包密码
        SmsCodeType_DeleteAccount,//注销账号
    }

    //各类事件定义
    public enum EUser_TgEvent {
        EUser_To_TdConfig, //配置tdlib data=null
        EUser_To_Check_Encryption, //检查密钥 data=null
        EUser_Td_Input_Phone, //输入手机号 data=null
        EUser_Td_Input_Code, //输入验证码 data=null
        EUser_Td_Input_Code_ByPasswordWay, //输入验证码 data=null 密码登录方式
        EUser_Td_Register, //注册 data=null
        //EUser_Td_Input_Password,
        EUser_Td_Ready, //td已准备好 data=null
        EUser_Td_Closed, //td已关闭 data=null
        EUser_Td_Closing, //td关闭中 data=null
        EUser_Td_Logout, //td已退出登录 data=null

        //消息会话相关
        EUser_Td_Connection_State_Changed, //连接状态变更 data=null
        EUser_Td_UpdateUserInfo, //更新当前用户信息 data=null
        EUser_Td_UpdateUserPrivacySettings, //当前用户隐私变化
        EUser_Td_UpdateContactInfo, //更新联系人信息 data = UserInfo
        EUser_Td_UpdateUserStatusInfo,//更新用户状态 data = UserInfo
        EUser_Td_AddNewContactInfo, //增加联系人 data = UserInfo
        EUser_Td_Message_Total_Unread_Changed, //消息未读总数更新 data = Long 未读总数 或者通过 UserInfo.getUserInfo().msgUnreadTotalCount获取
        EUser_Td_Chat_List_Changed, //最近会话列表个数变化 data = ChatInfo
        EUser_Td_Chat_Changed,//最近会话列表某个会话内容变化 data = ChatInfo
        EUser_Td_Chat_OutMessage_Readed,//发送的消息被读 data = ChatInfo
        EUser_Td_Chat_Last_Message_Changed,//最近会话列表某个会话最后一条消息变化 data = ChatInfo
        EUser_Td_Chat_New_Message,//新消息 data = MessageInfo
        EUser_Td_Chat_Pin_Message,//公告消息 data = PinMessage
        EUser_Td_Chat_Send_Message_Success,//发送成功 data = MessageInfo, dataEx = Long, old_message_id
        EUser_Td_Chat_Send_Message_Fail,//发送失败 data = MessageInfo, dataEx = Long, old_message_id
        EUser_Td_Chat_Delete_Message,//删除消息 data = DeleteMessagesInfo
        EUser_Td_Chat_Title_Changed,//最近会话标题修改 data = ChatInfo
        EUser_Td_Chat_Photo_Changed,//最近会话头像修改 data = ChatInfo
        EUser_Td_Chat_Permissions_Changed,//最近会话权限变更 data = ChatInfo
        EUser_Td_Chat_At_Someone,//at某人 data = UserInfo, dataEx = Long, chatId
        EUser_Td_Chat_Dm_At_Someone,//dm at某人 data = UserInfo, dataEx = Long, chatId
        EUser_Td_Chat_Bg_Changed,//会话背景改变 data = chatId
        EUser_Td_Chat_Super_Group_info,//群消息 data = SuperGroupInfo，dataEx = supergroup_id
        EUser_Td_Chat_Typing,//新消息 data = UpdateChatActionInfo
        EUser_Td_Chat_User_Full_Info,//userFullInfo改变 data：userId dataEx = UserFullInfo
        EUser_Td_Chat_Online_Count,//在线个数 data：online_member_count
        EUser_Td_Chat_Update_Secret,//更新加密聊天状态 data:SecretChatInfo
        EUser_Td_Remove_Contact,//删除联系人， data：userId
        EUser_Td_Chat_Update_Reaction,//评论表情  data:MessageReactionInfo
        EUser_Td_Chat_Send_Reaction,//评论表情  data:UiMessage  dataEx = reactionId

        //朋友圈
        EUser_Td_update_Blog_Follow,//updateBlogFollow关注动态事件
        EUser_Td_update_Blog_Content,//updateBlogContent更新动态,data:blog_id,dataEx:BlogContent
        EUser_Td_update_Circle_Unread_count,//data:int
        EUser_Td_Delete_Blog,//data:long BlogId

        //文件通知相关
        EUser_Td_Contact_Photo_Ok, //联系人头像已准备好 data = UserInfo
        EUser_Td_Group_Photo_Ok, //讨论组头像已准备好 data = ChatInfo
        EUser_Td_Message_Photo_Ok, //消息图片已准备好 data = FileTaskInfo, dataEx = FileInfo
        EUser_Td_Message_Preview_Photo_Ok, //消息预览图片已准备好 data = FileTaskInfo, dataEx = FileInfo
        EUser_Td_Message_Video_Ok, //消息视频已准备好 data = FileTaskInfo, dataEx = FileInfo
        EUser_Td_Message_Audio_Ok, //消息语音已准备好 data = FileTaskInfo, dataEx = FileInfo
        EUser_Td_Message_Voice_Ok, //消息语音已准备好 data = FileTaskInfo, dataEx = FileInfo
        EUser_Td_Message_Document_Ok, //消息文件已准备好 data = FileTaskInfo, dataEx = FileInfo
        EUser_Td_Message_Animation_Ok, //消息GIF已准备好 data = FileTaskInfo, dataEx = FileInfo

        //群组资料相关
        EUser_Td_Group_Basic_Info_Changed, //普通群组信息变更 data = BasicGroupInfo
        EUser_Td_Group_Basic_Full_Info_Changed, //普通群组信息变更 data = BasicGroupFullInfo, dataEx = Long, basic_group_id
        EUser_Td_Group_Super_Info_Changed, //超级群组信息变更 data = SuperGroupInfo
        EUser_Td_Group_Super_Full_Info_Changed, //超级群组信息变更 data = SuperGroupFullInfo, dataEx = Long, supergroup_id
        EUser_Td_Group_Permission_Change,//群权限 data = GroupManagePermissionInfo
        EUser_Td_Group_Keywords_Change,//群关键字 data = GroupManagePermissionInfo
        EUser_Td_Group_User_Nick_Name,
        EUser_Td_Group_User_Nick_Name_GET,

        //语音视频通话相关
        EUser_Call_State_Changed,   //通话状态改变
        EUser_Headset_State_Changed,//耳机插拔改变
        EUser_Refresh_Call_Time,    //刷新通话时间
        EUser_Incoming_New_Call,    //来电
        EUser_Call_Local_Voice_Mute_Changed, //语音本地静音改变

        //配置
        EUser_Tab_Ex_Menu_Changed,  //tab扩展菜单变更
        EUser_App_Config_Changed,  //app配置变更
        EUser_App_All_Config_Changed,


        ECircle_Like_Update,//点赞更新 updateBlogLike  data = BlogReplyInfo
        ECircle_Follow_Update,//关注更新 updateBlogFollow data = BlogUserInfo
        ECircle_Add_Reply,//评论 updateBlogReply data = BlogReplyInfo
        ECircle_Get_Blog,//获取说说详情
        ECircle_Send_Blog_Start,
        ECircle_Send_Blog_Success,
        ECircle_Send_Blog_Fail,
        ECircle_Send_Blog_Progressing,
    }

    //系统公告userid
    public static final long TG_USERID_SYSTEM_NOTICE = 777000;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="单例">
    private static final String TAG = "TelegramManager";
    private volatile static TelegramManager telegramManager;
    private final TgData tgData = new TgData();
    HandlerThread mWorkHandlerThread = new HandlerThread("tg_work_handlerThread");
    Handler workHandler;
    Handler mainHandler = new Handler(Looper.getMainLooper());

    private TelegramManager() {
        initTelegramManager();
    }

    public static TelegramManager getTelegramManager() {
        if (telegramManager == null) {
            synchronized (TelegramManager.class) {
                if (telegramManager == null) {
                    telegramManager = new TelegramManager();
                }
            }
        }
        return telegramManager;
    }

    public TgData getTgData() {
        return tgData;
    }

    private void initTelegramManager() {
        mWorkHandlerThread.start();
        //工作线程，处理tg消息收发
        workHandler = new Handler(mWorkHandlerThread.getLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                if (msg.obj != null) {
                    if (msg.obj instanceof TgTask) {
                        //发送请求
                        TgTask<Object> task = (TgTask<Object>) msg.obj;
                        if (getTgData().isValid()) {
                            JsonClient.send(tgData.getTdClient(), new Gson().toJson(task.request));
                            if (!task.nonTimeout) {
                                //设置超时
                                Runnable checkTimeOutTask = checkTimeOutTask(task);
                                timeoutTask.put(task.rtId, checkTimeOutTask);
                                workHandler.postDelayed(checkTimeOutTask, task.timeOutDuration);
                            }
                        }
                    } else if (msg.obj instanceof String) {
                        //接收到的报文
                        String rvJson = (String) msg.obj;
                        parseReceiveJson(rvJson);
                    } else if (msg.obj instanceof Integer) {
                        //移除任务
                        tgData.removeTgTask((Integer) msg.obj);
                        //移除超时设置
                        Runnable runnable = timeoutTask.remove((Integer) msg.obj);
                        if (runnable != null)
                            workHandler.removeCallbacks(runnable);
                    } else {
                        Constants.Loge(TAG, "workHandler message 未被处理, " + msg.obj);
                    }
                }
            }
        };
        //初始化tdlib
        tgData.setTdClient(JsonClient.create());
        //接收tg消息
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (!getTgData().isValid()) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        String json = JsonClient.receive(tgData.getTdClient(), 10);
                        if (!StringUtils.isEmpty(json)) {
                            Message msg = Message.obtain();
                            msg.obj = json;
                            workHandler.sendMessage(msg);
                        }
                    }
                }
            }
        }).start();
    }

    //重新初始化
    public void reInitTdlib() {
        if (!tgData.isValid()) {
            tgData.setUserState(GoUserState.GoUserState_Unkown);
            tgData.setUserConnectionState(GoUserConnectionState.GoUserConnectionState_Connecting);
            tgData.setTdClient(JsonClient.create());
        }
    }

    //清除缓存
    public void cleanCurrentData() {
        tgData.setUserState(GoUserState.GoUserState_Unkown);
        tgData.setUserConnectionState(GoUserConnectionState.GoUserConnectionState_Connecting);
        tgData.setCurChatId(0);
        tgData.setTdClient(0);
        tgData.cleanCache();
    }

    public void addTask(String invoke, int rtId, Map<String, Object> funMap, TgResultBlock<Object> resultBlock) {
        addTask(invoke, rtId, false, funMap, resultBlock);
    }

    public void addTask(String invoke, int rtId, boolean nonTimeout, Map<String, Object> funMap, TgResultBlock<Object> resultBlock) {
        addTask(invoke,rtId,nonTimeout,30*1000,funMap,resultBlock);
    }

    public void addTask(String invoke, int rtId, boolean nonTimeout,long timeOut, Map<String, Object> funMap, TgResultBlock<Object> resultBlock) {
        //加入队列
        TgTask<Object> task = new TgTask<>();
        task.rtId = rtId;
        task.request = funMap;
        task.resultBlock = resultBlock;
        task.nonTimeout = nonTimeout;
        getTgData().addTgTask(task);
        //打印
        Constants.Logd(TAG, "invoke " + invoke + " " + funMap.toString());
        //发送请求
        Message msg = Message.obtain();
        msg.obj = task;
        workHandler.sendMessage(msg);
    }

    public void cancelTask(int rtId) {
        //发送请求
        Message msg = Message.obtain();
        msg.obj = (Integer) rtId;
        workHandler.sendMessage(msg);
    }

    public void setLogLevel() {//设置日志级别
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setLogVerbosityLevel");
        funMap.put("new_verbosity_level", 5);
        funMap.put("@extra", rtId);
        addTask("setLogLevel", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
            }
        });
    }
    public void setLogStream() {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> logStreamMap = new HashMap<>();
        logStreamMap.put("@type","logStreamFile");
        String logFileDis = App.getInstanse().getExternalCacheDir().getAbsolutePath()+"/TdLibLogs";
        try {
            File file = new File(logFileDis);
//            if(file.exists()){
//                file.delete();
//            }
        }catch (Exception e){
            e.printStackTrace();
        }catch (Error e){
            e.printStackTrace();
        }
        logStreamMap.put("path",logFileDis);
        logStreamMap.put("max_file_size",120*1024*1024);
        logStreamMap.put("redirect_stderr",true);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setLogStream");
        funMap.put("log_stream", logStreamMap);
        funMap.put("@extra", rtId);
        addTask("setLogStream", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
            }
        });
    }

    public void logout() {
        if (!getTgData().isValid()) {
            return;
        }

        ContactUtils.getIntance().clean();
        LocationHelper.getIntance().stopLocation();
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "logOut");
        funMap.put("@extra", rtId);
        addTask("logout", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
            }
        });
    }

    public void setLocation(AMapLocation location) {
        if (!getTgData().isValid()||location==null) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> locationMap = new HashMap<>();
        locationMap.put("latitude",location.getLatitude());
        locationMap.put("longitude",location.getLongitude());
        locationMap.put("horizontal_accuracy",location.getAccuracy());
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setLocation");
        funMap.put("location", locationMap);
        funMap.put("@extra", rtId);
        addTask("setLocation", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
            }
        });
    }

    private HashMap<String, BurnAfterWrappter> burnAfterReadMap = new HashMap<>();
    private HashMap<String,Disposable> burnAfterReadDisposableMap = new HashMap<>();



    public String apppendBurnTask(MessageInfo messageInfo, Consumer<String> consumer){
        final String key = String.format("%s-%s",messageInfo.chat_id,messageInfo.id);
        if(burnAfterReadMap.containsKey(key)&&burnAfterReadMap.get(key)!=null){
            burnAfterReadMap.get(key).consumer = consumer;
            burnAfterReadMap.put(key, burnAfterReadMap.get(key));
        }else{
            burnAfterReadMap.put(key, new BurnAfterWrappter(consumer));
        }

        if(!burnAfterReadDisposableMap.containsKey(key)){
            int countDownSeconds = messageInfo.barInfo!=null?messageInfo.barInfo.countDown:messageInfo.ttl;
            BurnAfterWrappter wrappter = burnAfterReadMap.get(key);
            if(wrappter!=null){
                wrappter.currentTimeStr = countDownSeconds+"s";
                burnAfterReadMap.put(key,wrappter);
            }
            Disposable countdownDisposable = Flowable.intervalRange(0, countDownSeconds, 0, 1, TimeUnit.SECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnNext(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            BurnAfterWrappter wrappter = burnAfterReadMap.get(key);
                            String value = ((countDownSeconds - aLong) + "s");
                            if(wrappter!=null){
                                if(wrappter.consumer!=null){
                                    wrappter.consumer.accept(value);
                                }
                                wrappter.currentTimeStr = value;
                                burnAfterReadMap.put(key,wrappter);
                            }

                        }
                    })
                    .doOnComplete(new Action() {
                        @Override
                        public void run() throws Exception {
                            if(messageInfo!=null){
                                ChatInfo chat = TelegramManager.getTelegramManager().getTgData().chatInfo(messageInfo.chat_id);
                                List<Long> ids = new ArrayList<>();
                                ids.add(messageInfo.id);
                                if(chat!=null&&chat.isGroup()){
                                    TelegramManager.getTelegramManager().deleteSuperGroupMessages(ActivityUtils.getTopActivity(),messageInfo.chat_id, ids, new TgResultBlock<TgResponse>() {
                                        @Override
                                        public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {

                                        }

                                        @Override
                                        public void onTimeout(Map<String, Object> request) {

                                        }
                                    });
                                }else {
                                    TelegramManager.getTelegramManager().deleteP2pMessages(ActivityUtils.getTopActivity(),messageInfo.chat_id, ids, true, new TgResultBlock<TgResponse>() {
                                        @Override
                                        public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {

                                        }

                                        @Override
                                        public void onTimeout(Map<String, Object> request) {

                                        }
                                    });
                                }

                            }

                            burnAfterReadMap.remove(key);
                        }
                    })
                    .subscribe();
            burnAfterReadDisposableMap.put(key,countdownDisposable);
        }
        BurnAfterWrappter wrappter = burnAfterReadMap.get(key);
        if(wrappter!=null){
            return wrappter.currentTimeStr;
        }else{
            return "";
        }

    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    public void cleanBurnTasks(){
        if(burnAfterReadDisposableMap.size()>0){
            burnAfterReadDisposableMap.forEach(new BiConsumer<String, Disposable>() {
                @Override
                public void accept(String s, Disposable disposable) {
                    if(disposable!=null&&!disposable.isDisposed()){
                        disposable.dispose();
                    }
                }
            });
        }
        burnAfterReadDisposableMap.clear();
        burnAfterReadMap.clear();
    }

    public void destroy() {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "destroy");
        funMap.put("@extra", rtId);
        if (getTgData().isValid()) {
            JsonClient.send(tgData.getTdClient(), new Gson().toJson(funMap));
            getTgData().setTdClient(0);
        }
        cleanBurnTasks();
    }


    public void close() {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "close");
        funMap.put("@extra", rtId);
        if (getTgData().isValid()) {
            JsonClient.send(tgData.getTdClient(), new Gson().toJson(funMap));
//            getTgData().setTdClient(0);
        }
        cleanBurnTasks();
    }

    private boolean isActivityDestroy(Context context) {
        if (context == null) return false;
        if (context instanceof Activity) {
            Activity a = (Activity) context;
            return a.isFinishing() || a.isDestroyed();
        }
        return false;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="超时处理">
    //30秒超时
    private static final long ACK_TIME_OUT = 30 * 1000;
    //超时集合
    private Map<Integer, Runnable> timeoutTask = new HashMap<>();

    public Runnable checkTimeOutTask(final TgTask task) {
        return new Runnable() {
            @Override
            public void run() {
                //移除任务
                tgData.removeTgTask(task.rtId);
                //移除超时设置
                Runnable runnable = timeoutTask.remove(task.rtId);
                if (runnable != null)
                    workHandler.removeCallbacks(runnable);
                //回调
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        task.resultBlock.onTimeout(task.request);
                    }
                });
            }
        };
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="接收报文解析">
    private void parseReceiveJson(String rvJson) {
        Constants.Logd(TAG, rvJson);
        try {
            JsonObject jsonObj = new Gson().fromJson(rvJson, JsonObject.class);
            if (jsonObj != null && jsonObj.has("@type")) {
                String type = jsonObj.get("@type").getAsString();
                int rtId = -1;
                if (jsonObj.has("@extra")) {
                    rtId = jsonObj.get("@extra").getAsInt();
                }
                if (rtId > 0) {
                    TgTask task = tgData.getTgTask(rtId);
                    if (task != null) {
                        //从队列移除
                        tgData.removeTgTask(rtId);
                        //移除超时设置
                        Runnable runnable = timeoutTask.remove(rtId);
                        if (runnable != null)
                            workHandler.removeCallbacks(runnable);
                        //设置返回报文
                        //task.response = jsonObj;
                        //回调
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                task.resultBlock.onResult(task.request, jsonObj, null);
                            }
                        });

                        if ("updateAuthorizationState".equals(type)) {//鉴权状态变更
                            dealAuthorizationUpdate(jsonObj.getAsJsonObject("authorization_state"));
                        }
                        return;
                    }
                }
                if ("updateAuthorizationState".equals(type)) {//鉴权状态变更
                    dealAuthorizationUpdate(jsonObj.getAsJsonObject("authorization_state"));
                } else if ("updateOption".equals(type)) {
                    String type_name = jsonObj.get("name").getAsString();
                    if (!StringUtils.isEmpty(type_name) && "my_id".equals(type_name)) {//当前账号userid
                        JsonObject valueDic = jsonObj.getAsJsonObject("value");
                        if (valueDic != null) {
                            long id = valueDic.get("value").getAsLong();
                            mainHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    UserInfo.getUserInfo().id = id;
                                    AuthUserManager.getAuthUserManager().updateCurrentUserId(id);
                                }
                            });
                        }
                    }
                } else if ("updateUser".equals(type)) {//更新当前用户或者联系人资料
                    JsonObject userDic = jsonObj.getAsJsonObject("user");
                    if (userDic != null) {
                        String userType = userDic.get("@type").getAsString();
                        if (!StringUtils.isEmpty(userType)) {
                            parseUserInfo(userDic);
                        }
                    }
                } else if("updateUserStatus".equals(type)){
                    JsonObject userStatusJsonObject = jsonObj.getAsJsonObject("status");
                    if(userStatusJsonObject!=null){
                        UserStatus userStatus = new Gson().fromJson(userStatusJsonObject, UserStatus.class);
                        long userId = jsonObj.get("user_id").getAsLong();
                        UserInfo user = UserInfo.getUserInfo(userId);
                        user.status = userStatus;
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_UpdateUserStatusInfo, user));
                    }
                }else if ("updateUserPrivacySettingRules".equals(type)) {//更新个人隐私设置
                    UserPrivacySettingInfo settingInfo = new Gson().fromJson(jsonObj, UserPrivacySettingInfo.class);
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_UpdateUserPrivacySettings, settingInfo));
                } else if("updateUserChatAction".equals(type)){
                    UpdateChatActionInfo updateChatActionInfo = new Gson().fromJson(jsonObj, UpdateChatActionInfo.class);
                    if(updateChatActionInfo!=null){
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Typing,updateChatActionInfo));
                    }
                } else if (dealConnectionState(type, jsonObj)) {//连接状态处理
                } else if (dealChatList(type, jsonObj)) {//最近会话消息处理
                } else if (dealNewMessage(type, jsonObj)) {//新消息处理
                } else if (dealGroup(type, jsonObj)) {//群组相关
                } else if (dealNewCustomEvent(type, jsonObj)) {//自定义消息相关
                } else if("updateSavedAnimations".equals(type)){
                    StickerManager.getInstance().refreshStickerCategory();
                }else if("updateChatPinnedMessage".equals(type)){
                    PinMessage pinMessage = new Gson().fromJson(jsonObj, PinMessage.class);
                    if(pinMessage!=null){
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Pin_Message, pinMessage));
                    }
                }else if("updateUserFullInfo".equals(type)){
                    try {
                        long userId = jsonObj.get("user_id").getAsLong();
                        UserFullInfo fullInfo = new Gson().fromJson(jsonObj.get("user_full_info").getAsJsonObject(), UserFullInfo.class);
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_User_Full_Info, userId,fullInfo));
                    }catch (Exception e){

                    }
                }else if("updateBlogContent".equals(type)){

                }else if("updateBlogLike".equals(type)){
                    BlogReplyInfo blogReplyInfo = new Gson().fromJson(jsonObj, BlogReplyInfo.class);
                    if(blogReplyInfo!=null){
                        getCircleUnreadCount();
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.ECircle_Like_Update, blogReplyInfo));
                    }
                }else if("updateBlogFollow".equals(type)){
                    BlogUserInfo blogUserInfo = new Gson().fromJson(jsonObj, BlogUserInfo.class);
                    if(blogUserInfo!=null){
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.ECircle_Follow_Update, blogUserInfo));
                    }
                }else if("updateBlogReply".equals(type)){
                    BlogReplyInfo blogReplyInfo = new Gson().fromJson(jsonObj.get("new_reply").getAsJsonObject(), BlogReplyInfo.class);
                    if(blogReplyInfo!=null){
                        getCircleUnreadCount();
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.ECircle_Add_Reply, blogReplyInfo));
                    }
                }else if("updateBlogSendSucceeded".equals(type)){
                    BlogInfo blogInfo = new Gson().fromJson(jsonObj.get("blog").getAsJsonObject(), BlogInfo.class);
                    if(blogInfo!=null){
                        long oldBlogId = jsonObj.get("old_blog_id").getAsLong();
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.ECircle_Send_Blog_Success, blogInfo,oldBlogId));
                    }
                }else if("updateBlogSendFailed".equals(type)){
//                    ToastUtils.showShort("发布失败");
                    long oldBlogId = jsonObj.get("old_blog_id").getAsLong();
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.ECircle_Send_Blog_Fail,oldBlogId));
                }else if("updateFile".equals(type)){
                    FileInfo fileInfo = new Gson().fromJson(jsonObj.get("file").getAsJsonObject(), FileInfo.class);
                    if(fileInfo!=null){
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.ECircle_Send_Blog_Progressing, fileInfo));
                    }
                }else if("updateChatOnlineMemberCount".equals(type)){
                    ChatOnlineMemberCountInfo countInfo = new Gson().fromJson(jsonObj, ChatOnlineMemberCountInfo.class);
                    if(countInfo!=null){
                        ChatInfo chatInfo = TelegramManager.getTelegramManager().getTgData().chatInfo(countInfo.chat_id);
                        if(chatInfo!=null){
                            chatInfo.online_member_count = countInfo.online_member_count;
                        }
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Online_Count,countInfo));
                    }

                }else if("updateSecretChat".equals(type)){
//                    {"@type":"updateSecretChat","secret_chat":{"@type":"secretChat","id":1203239110,"user_id":136817699,"state":{"@type":"secretChatStatePending"},"is_outbound":true,"ttl":0,"key_hash":"","layer":46}}

                    SecretChatInfo secretChatInfo = new Gson().fromJson(jsonObj.get("secret_chat").getAsJsonObject(), SecretChatInfo.class);
                    if(secretChatInfo!=null){
                        if(secretChatInfo.isClosed()){
                            ChatInfo chatInfo = TelegramManager.getTelegramManager().getTgData().removeChatBySecretChatId(secretChatInfo.id);
                            if(chatInfo!=null){
                                TelegramManager.getTelegramManager().deleteChatHistory(ActivityUtils.getTopActivity(),chatInfo.id,true,null);
                            }

                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_List_Changed, chatInfo));
                        }
                        EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Update_Secret,secretChatInfo));
                    }
                }else
//                    if("updateChatUnreadMentionCount".equals(type))
                {

                }
            } else {
                Constants.Loge(TAG, "异常报文: " + rvJson);
            }
        } catch (Exception e) {
            Constants.Loge(TAG, "异常报文: " + rvJson + ", " + e.getLocalizedMessage());
        }
    }

    private UserInfo parseUserInfo(JsonObject userDic) {//用户信息
        UserInfo user = new Gson().fromJson(userDic, UserInfo.class);
        if (user.id == UserInfo.getUserInfo().id) {//当前用户
            UserInfo.getUserInfo().first_name = user.first_name;
            UserInfo.getUserInfo().last_name = user.last_name;
            UserInfo.getUserInfo().phone_number = user.phone_number;
            UserInfo.getUserInfo().username = user.username;
            UserInfo.getUserInfo().profile_photo = user.profile_photo;
            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_UpdateUserInfo, null));
            //当前是否用户名密码登录方式，此策略执行后，跟手机号码登录保持一致
            if (UserInfo.getUserInfo().isPasswordLoginType) {
                //更新主键为手机号码
                AuthUserManager.getAuthUserManager().updateCurrentUserPhone(UserInfo.getUserInfo().phone_number);
            }
        } else {//联系人
            boolean isAdd = false;
            UserInfo prev = tgData.contactInfo(user.id);
            if (prev != null) {//更新
                if (prev.displayName().equals(user.displayName())) {//昵称未改变
                    user.displayName_full_py = prev.displayName_full_py;
                }
                tgData.addOrUpdateContact(user);
            } else {//新增
                isAdd = true;
                tgData.addOrUpdateContact(user);
            }
            //补充拼音
            if (StringUtils.isEmpty(user.displayName_full_py)) {
                user.displayName_full_py = Pinyin.toPinyin(user.displayName(), "");
            }
            if (isAdd) {
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_AddNewContactInfo, user));
            } else {
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_UpdateContactInfo, user));
            }
        }
        return user;
    }

    public void doregisterDevice(){
        try {
            String registrationID = JPushInterface.getRegistrationID(App.getInstanse());;
            if(!TextUtils.isEmpty(registrationID)){
                TelegramManager.getTelegramManager().registerDevice(App.getInstanse(), registrationID, new TgResultBlock<TgResponse>() {
                    @Override
                    public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {

                    }

                    @Override
                    public void onTimeout(Map<String, Object> request) {

                    }
                });
                if(!com.zy.openchat.util.SPUtils.getBoolean(App.getInstanse(),Constants.SPU_FOR_NOTIFICATION_SHOW,true)){
//                    XGPushManager.unregisterPush(App.getInstanse());
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void dealAuthorizationUpdate(JsonObject authorization_state) {//用户鉴权
        if (authorization_state != null && authorization_state.has("@type")) {
            String type = authorization_state.get("@type").getAsString();
            if ("authorizationStateWaitTdlibParameters".equals(type)) {
                tgData.setUserState(GoUserState.GoUserState_TdlibParameters);
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_To_TdConfig, null));
                //设置日志级别
                setLogLevel();
                setLogStream();
                queryAppConfigWithoutLogin();
            } else if ("authorizationStateWaitEncryptionKey".equals(type)) {
                tgData.setUserState(GoUserState.GoUserState_WaitEncryptionKey);
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_To_Check_Encryption, null));
            } else if ("authorizationStateWaitPhoneNumber".equals(type)) {
                tgData.setUserState(GoUserState.GoUserState_WaitPhoneNumber);
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Input_Phone, null));
            } else if ("authorizationStateWaitCode".equals(type)) {
                tgData.setUserState(GoUserState.GoUserState_WaitCode);
                if(UserInfo.getUserInfo().isPasswordRegisterType){
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Input_Code, null));
                }else if (UserInfo.getUserInfo().isPasswordLoginType) {
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Input_Code_ByPasswordWay, null));
                } else {
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Input_Code, null));
                }
            } else if ("authorizationStateWaitRegistration".equals(type)) {
                tgData.setUserState(GoUserState.GoUserState_WaitRegistration);
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Register, null));
            }
//            else if ("authorizationStateWaitPassword".equals(type)) {
//                tgData.setUserState(GoUserState.GoUserState_WaitPassword);
//                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Input_Password, null));
//            }
            else if ("authorizationStateReady".equals(type)) {
                tgData.setUserState(GoUserState.GoUserState_Ready);
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Ready, null));
            } else if ("authorizationStateClosed".equals(type)) {
                tgData.setUserState(GoUserState.GoUserState_Closed);
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Closed, null));
            } else if ("authorizationStateClosing".equals(type)) {
                tgData.setUserState(GoUserState.GoUserState_Closing);
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Closing, null));
            } else if ("authorizationStateLoggingOut".equals(type)) {
                tgData.setUserState(GoUserState.GoUserState_LoggingOut);
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Logout, null));
            }
//            else if ("authorizationStateWaitOtherDeviceConfirmation".equals(type)) {
//                tgData.setUserState(GoUserState.GoUserState_WaitOtherDeviceConfirmation);
//                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Logout, null));
//            }
            else {
                Constants.Loge(TAG, "未处理状态: " + authorization_state.toString());
            }
        }
    }

    private boolean dealConnectionState(String type, JsonObject data) {//用户状态
        if ("updateConnectionState".equals(type)) {
            JsonObject stateDic = data.getAsJsonObject("state");
            if (stateDic != null && stateDic.has("@type")) {
                String stateStr = stateDic.get("@type").getAsString();
                if ("connectionStateReady".equals(stateStr)) {
                    cancletdlibCountDown();
                    tgData.setUserConnectionState(GoUserConnectionState.GoUserConnectionState_StateReady);
                } else if ("connectionStateUpdating".equals(stateStr)) {
                    cancletdlibCountDown();
                    tgData.setUserConnectionState(GoUserConnectionState.GoUserConnectionState_Updating);
                } else {
                    tgData.setUserConnectionState(GoUserConnectionState.GoUserConnectionState_Connecting);
                }
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Connection_State_Changed, null));
            }
            return true;
        }
        return false;
    }

    private boolean dealChatList(String type, JsonObject data) {//会话处理
        if ("updateNewChat".equals(type)) {//新最近会话
            JsonObject chatDic = data.getAsJsonObject("chat");
            if (chatDic != null) {
                ChatInfo chat = new Gson().fromJson(chatDic, ChatInfo.class);
                ChatInfo curChat = tgData.chatInfo(chat.id);
                if (curChat != null) {
                    mainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            curChat.copyChatContent(chat);
                            curChat.title_full_py = Pinyin.toPinyin(curChat.title, "");
                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Changed, curChat));
                        }
                    });
                } else {
                    chat.title_full_py = Pinyin.toPinyin(chat.title, "");
                    tgData.addOrUpdateChat(chat);
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_List_Changed, curChat));
                }
            }
            return true;
        } else if ("updateChatLastMessage".equals(type)) {//最近会话-更新最后一条消息
            JsonObject messageDic = data.getAsJsonObject("last_message");
            if (messageDic != null) {
                MessageInfo last = new Gson().fromJson(messageDic, MessageInfo.class);
                ChatInfo chat = tgData.chatInfo(last.chat_id);
                if (chat != null) {

                    if(data.has("positions")&&data.get("positions").isJsonArray()&&data.get("positions").getAsJsonArray().size()>0){
                        long order = 0;
                        boolean is_pinned = false;
                        JsonObject position = data.get("positions").getAsJsonArray().get(0).getAsJsonObject();

                        if(position.getAsJsonObject().has("is_pinned")){
                            is_pinned = position.getAsJsonObject().get("is_pinned").getAsBoolean();
                        }

                        if(position.getAsJsonObject().has("order")){
                            order = position.getAsJsonObject().get("order").getAsLong();
                        }
                        chat.order = order;
                        chat.is_pinned = is_pinned;
                    }
                    parseMessageContent(messageDic.getAsJsonObject("content"), last);
                    mainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            chat.lastMessage = last;
                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Last_Message_Changed, chat));
                        }
                    });
                }

            } else {
                if (data.has("chat_id")) {
                    long chatId = data.get("chat_id").getAsLong();
                    ChatInfo chat = tgData.chatInfo(chatId);
                    if (chat != null) {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                chat.lastMessage = null;
                                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Last_Message_Changed, chat));
                            }
                        });
                    }
                }
            }
            return true;
        } else if ("updateChatReadInbox".equals(type)) {//最近会话-未读角标变化
            //{"@type":"updateChatReadInbox","chat_id":136817704,"last_read_inbox_message_id":357564416,"unread_count":9}
            if (data.has("chat_id")) {
                long chatId = data.get("chat_id").getAsLong();
                ChatInfo chat = tgData.chatInfo(chatId);
                if (chat != null) {
                    //更新未读数
                    int unread_count = 0;
                    if (data.has("unread_count"))
                        unread_count = data.get("unread_count").getAsInt();
                    chat.unread_count = unread_count;
                    //更新已读索引
                    int last_read_inbox_message_id = 0;
                    if (data.has("last_read_inbox_message_id"))
                        last_read_inbox_message_id = data.get("last_read_inbox_message_id").getAsInt();
                    chat.last_read_inbox_message_id = last_read_inbox_message_id;
                    //发送通知
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Changed, chat));
                }
            }
            return true;
        } else if ("updateChatReadOutbox".equals(type)) {//最近会话-发送消息被读
            //{"@type":"updateChatReadOutbox","chat_id":-1001073741852,"last_read_outbox_message_id":60817408}
            if (data.has("chat_id")) {
                long chatId = data.get("chat_id").getAsLong();
                ChatInfo chat = tgData.chatInfo(chatId);
                if (chat != null) {
                    //更新已读索引
                    int last_read_outbox_message_id = 0;
                    if (data.has("last_read_outbox_message_id"))
                        last_read_outbox_message_id = data.get("last_read_outbox_message_id").getAsInt();
                    chat.last_read_outbox_message_id = last_read_outbox_message_id;
                    //发送通知
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_OutMessage_Readed, chat));
                }
            }
            return true;
        } else if ("updateChatTitle".equals(type)) {//最近会话-标题修改
            //{"@type":"updateChatTitle","chat_id":-32,"title":"Test01"}
            if (data.has("chat_id")) {
                long chatId = data.get("chat_id").getAsLong();
                ChatInfo chat = tgData.chatInfo(chatId);
                if (chat != null) {
                    //更新已读索引
                    String title = "";
                    if (data.has("title"))
                        title = data.get("title").getAsString();
                    chat.title = title;
                    chat.title_full_py = Pinyin.toPinyin(chat.title, "");
                    //发送通知
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Title_Changed, chat));
                }
            }
            return true;
        } else if ("updateChatPhoto".equals(type)) {//最近会话-修改头像
            //{"@type":"updateChatPhoto","chat_id":-36,"photo":{"@type":"chatPhoto",
            if (data.has("chat_id")) {
                long chatId = data.get("chat_id").getAsLong();
                ChatInfo chat = tgData.chatInfo(chatId);
                if (chat != null) {
                    JsonObject photoDic = data.getAsJsonObject("photo");
                    if (photoDic != null) {
                        ProfilePhoto photo = new Gson().fromJson(photoDic, ProfilePhoto.class);
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                chat.photo = photo;
                                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Photo_Changed, chat));
                            }
                        });
                    }
                }
            }
            return true;
        } else if ("updateChatPermissions".equals(type)) {//最近会话-管理员修改了权限
            if (data.has("chat_id")) {
                long chatId = data.get("chat_id").getAsLong();
                ChatInfo chat = tgData.chatInfo(chatId);
                if (chat != null) {
                    JsonObject permissionsDic = data.getAsJsonObject("permissions");
                    if (permissionsDic != null) {
                        ChatPermissions permissions = new Gson().fromJson(permissionsDic, ChatPermissions.class);
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                chat.permissions = permissions;
                                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Permissions_Changed, chat));
                            }
                        });
                    }
                }
            }
            return true;
        } else if ("updateChatIsPinned".equals(type)||"updateChatPosition".equals(type)) {//最近会话-置顶
            //{"@type":"updateChatIsPinned","chat_id":136817691,"is_pinned":true,"order":"9221294784512000001"}
//            {"@type":"updateChatPosition","chat_id":-1001073741831,"position":{"@type":"chatPosition","list":{"@type":"chatListMain"},"order":"7000233798361153536","is_pinned":false}}
            if (data.has("chat_id")) {
                long chatId = data.get("chat_id").getAsLong();
                ChatInfo chat = tgData.chatInfo(chatId);
                if (chat != null) {
                    //更新置顶
                    boolean is_pinned = false;
                    if (data.has("is_pinned")){
                        is_pinned = data.get("is_pinned").getAsBoolean();
                    }else if(data.has("position")&&data.get("position").isJsonObject()){
                        if(data.get("position").getAsJsonObject().has("is_pinned")){
                            is_pinned = data.get("position").getAsJsonObject().get("is_pinned").getAsBoolean();
                        }
                    }
                    long order = 0;
                    if (data.has("order")){
                        order = data.get("order").getAsLong();
                    }else if(data.has("position")&&data.get("position").isJsonObject()){
                        if(data.get("position").getAsJsonObject().has("order")){
                            order = data.get("position").getAsJsonObject().get("order").getAsLong();
                        }
                    }
                    chat.order = order;
                    chat.is_pinned = is_pinned;
                    //发送通知
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_List_Changed, chat));
                }
            }
            return true;
        } else if ("updateChatDefaultDisableNotification".equals(type)) {//最近会话-提醒设置
            //{"@type":"updateChatDefaultDisableNotification","chat_id":136817691,"default_disable_notification":false}
            if (data.has("chat_id")) {
                long chatId = data.get("chat_id").getAsLong();
                ChatInfo chat = tgData.chatInfo(chatId);
                if (chat != null) {
                    //更新通知提醒
                    boolean default_disable_notification = false;
                    if (data.has("default_disable_notification"))
                        default_disable_notification = data.get("default_disable_notification").getAsBoolean();
                    chat.default_disable_notification = default_disable_notification;
                    //发送通知
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Changed, chat));
                }
            }
            return true;
        } else {
            return false;
        }
    }

    private void newMessage(MessageInfo msg) {
        //新消息处理
        if (msg != null) {
            if (msg.isLocalMessage() || msg.chat_id == UserInfo.getUserInfo().id) {
                List<Long> list = new ArrayList<>();
                list.add(msg.id);
                setMessagesReaded(msg.chat_id, list);
            } else {
                if (!msg.isOutgoing() && msg.chat_id != getTgData().getCurChatId() && !msg.isRead()) {
                    ChatInfo chat = getTgData().chatInfo(msg.chat_id);
                    if (chat != null && chat.default_disable_notification) {//不提醒
                    } else {
                        if(chat!=null&&chat.last_read_inbox_message_id>0&&msg.id<=chat.last_read_inbox_message_id){
                            return;
                        }
                        if (App.getInstanse().appLifecycle.isForeground()) {
                            //前台
                            //震动
                            LocalNotificationHelper.PhoneVibrator(App.getInstanse());
                            //声音
                            LocalNotificationHelper.playRingtone(App.getInstanse());

                        } else {
                            //本地通知
                            LocalNotificationHelper.showMessageNotification(App.getInstanse(), msg);
                        }
                    }
                } else {
                   // Constants.Logd(TAG, "msg.isOutgoing(): " + msg.isOutgoing()  + " " + "msg.chat_id != getTgData().getCurChatId():" + msg.chat_id + "=" +  getTgData().getCurChatId() + " " + "msg.isRead()" + msg.isRead());
                }
            }
        }
    }

    private boolean dealNewMessage(String type, JsonObject data) {
        if ("updateNewMessage".equals(type)) {//新消息，包括发送的消息
            JsonObject messageDic = data.getAsJsonObject("message");
            if (messageDic != null) {
                MessageInfo msg = new Gson().fromJson(messageDic, MessageInfo.class);
                parseMessageContent(messageDic.getAsJsonObject("content"), msg);
                //发送通知
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_New_Message, msg));
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        newMessage(msg);
                    }
                });
            }
            return true;
        } else if ("updateMessageSendSucceeded".equals(type)) {//消息发送成功
            JsonObject messageDic = data.getAsJsonObject("message");
            if (messageDic != null) {
                MessageInfo msg = new Gson().fromJson(messageDic, MessageInfo.class);
                parseMessageContent(messageDic.getAsJsonObject("content"), msg);
                long old_message_id = 0;
                if (data.has("old_message_id"))
                    old_message_id = data.get("old_message_id").getAsLong();
                //发送通知
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Send_Message_Success, msg, (Long) old_message_id));
            }
            return true;
        } else if ("updateMessageSendFailed".equals(type)) {//消息发送失败
            JsonObject messageDic = data.getAsJsonObject("message");
            if (messageDic != null) {
                MessageInfo msg = new Gson().fromJson(messageDic, MessageInfo.class);
                parseMessageContent(messageDic.getAsJsonObject("content"), msg);
                long old_message_id = 0;
                if (data.has("old_message_id"))
                    old_message_id = data.get("old_message_id").getAsLong();
                //发送通知
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Send_Message_Fail, msg, (Long) old_message_id));
            }
            return true;
        } else if ("updateDeleteMessages".equals(type)) {//消息被删除
            //{"@type":"updateDeleteMessages","chat_id":136817700,"message_ids":[177209346],"is_permanent":true,"from_cache":false}
            DeleteMessagesInfo deleteMsgs = new Gson().fromJson(data, DeleteMessagesInfo.class);
            //发送通知
            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Delete_Message, deleteMsgs));
            return true;
        } else {
            return false;
        }
    }

    private boolean dealGroup(String type, JsonObject data) {
        if ("updateBasicGroup".equals(type)) {//普通群组
            JsonObject basicGroupDic = data.getAsJsonObject("basic_group");
            if (basicGroupDic != null) {
                BasicGroupInfo info = new Gson().fromJson(basicGroupDic, BasicGroupInfo.class);
                //发送通知
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_Basic_Info_Changed, info));
            }
            return true;
        } else if ("updateBasicGroupFullInfo".equals(type)) {//普通群组Full
            JsonObject basicFullGroupDic = data.getAsJsonObject("basic_group_full_info");
            if (basicFullGroupDic != null) {
                long basic_group_id = 0;
                if (data.has("basic_group_id"))
                    basic_group_id = data.get("basic_group_id").getAsLong();
                BasicGroupFullInfo info = new Gson().fromJson(basicFullGroupDic, BasicGroupFullInfo.class);
                //发送通知
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_Basic_Full_Info_Changed, info, (Long) basic_group_id));
            }
            return true;
        } else if ("updateSupergroup".equals(type)) {//超级群组
            JsonObject superGroupDic = data.getAsJsonObject("supergroup");
            if (superGroupDic != null) {
                SuperGroupInfo info = new Gson().fromJson(superGroupDic, SuperGroupInfo.class);
                if(info!=null){
                    if(!info.isMyGroup()){
                        if(getTgData().addNotMemberSuperGroup(info.id)){
                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_List_Changed, null));
                        }
                    }else{
                        if(getTgData().removeNotMemberSuperGroup(info.id)){
                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_List_Changed, null));
                        }
                    }
                    //发送通知
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_Super_Info_Changed, info));
                }
            }
            return true;
        } else if ("updateSupergroupFullInfo".equals(type)) {//超级群组Full
            JsonObject superFullGroupDic = data.getAsJsonObject("supergroup_full_info");
            if (superFullGroupDic != null) {
                long supergroup_id = 0;
                if (data.has("supergroup_id"))
                    supergroup_id = data.get("supergroup_id").getAsLong();
                SuperGroupFullInfo info = new Gson().fromJson(superFullGroupDic, SuperGroupFullInfo.class);
                //发送通知
                EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_Super_Full_Info_Changed, info, (Long) supergroup_id));
            }
            return true;
        } else {
            return false;
        }
    }

    private boolean dealNewCustomEvent(String type, JsonObject data) {
        if ("updateNewCustomEvent".equals(type)) {//自定义消息
            if (data.has("event")) {
                String eventJson = data.get("event").getAsString();
                if (!StringUtils.isEmpty(eventJson)) {
                    JsonObject eventDic = new Gson().fromJson(eventJson, JsonObject.class);
                    if (eventDic != null && eventDic.has("action")) {
                        String actionStr = eventDic.get("action").getAsString();
                        if (!StringUtils.isEmpty(actionStr)) {
                            if ("call.onInvite".equals(actionStr)) {//被邀请通话
                                if (eventDic.has("data")) {
                                    JsonObject eventData = eventDic.getAsJsonObject("data");
                                    if (eventData != null) {
                                        RemoteCallInfo callInfo = new Gson().fromJson(eventData, RemoteCallInfo.class);
                                        callInfo.isTimeOut = false;
                                        mainHandler.post(new Runnable() {
                                            @Override
                                            public void run() {
                                                CallManager.getCallManager().newIncomingCall(callInfo);
                                            }
                                        });
                                    }
                                }
                            }else if ("call.onCancel".equals(actionStr)) {//通话被取消
                                if (eventDic.has("data")) {
                                    JsonObject eventData = eventDic.getAsJsonObject("data");
                                    if (eventData != null) {
                                        RemoteCallInfo callInfo = new Gson().fromJson(eventData, RemoteCallInfo.class);
                                        callInfo.isTimeOut = false;
                                        mainHandler.post(new Runnable() {
                                            @Override
                                            public void run() {
                                                CallManager.getCallManager().cancelCall(callInfo);
                                            }
                                        });
                                    }
                                }
                            }else if ("call.onLeave".equals(actionStr)) {//某人离开通话
                                if (eventDic.has("data")) {
                                    JsonObject eventData = eventDic.getAsJsonObject("data");
                                    if (eventData != null) {
                                        RemoteCallInfo callInfo = new Gson().fromJson(eventData, RemoteCallInfo.class);
                                        callInfo.isTimeOut = false;
                                        mainHandler.post(new Runnable() {
                                            @Override
                                            public void run() {
                                                CallManager.getCallManager().leaveCall(callInfo);
                                            }
                                        });
                                    }
                                }
                            }else if("chats.rights.onUpdate".equals(actionStr)){
                                if (eventDic.has("data")) {
                                    JsonObject eventData = eventDic.getAsJsonObject("data");
                                    if (eventData != null) {
                                        GroupManagePermissionInfo permissionInfo = new Gson().fromJson(eventData, GroupManagePermissionInfo.class);
                                        if(permissionInfo!=null){
                                            permissionInfo.chatId = ChatInfo.toLocalChatId(permissionInfo.chatId);
                                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_Permission_Change, permissionInfo));
                                        }

                                    }
                                }
                            }else if("chats.keywords.onUpdate".equals(actionStr)){
                                if (eventDic.has("data")) {
                                    JsonObject eventData = eventDic.getAsJsonObject("data");
                                    if (eventData != null) {
                                        GroupManagePermissionInfo permissionInfo = new Gson().fromJson(eventData, GroupManagePermissionInfo.class);
                                        if(permissionInfo!=null) {
                                            permissionInfo.chatId = ChatInfo.toLocalChatId(permissionInfo.chatId);
                                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_Keywords_Change, permissionInfo));
                                        }
                                    }
                                }
                            }else if("chats.nickname,onUpdate".equals(actionStr)){
                                if (eventDic.has("data")) {
                                    JsonObject eventData = eventDic.getAsJsonObject("data");
                                    if (eventData != null) {
                                        GroupUserInfo groupUserInfo = new Gson().fromJson(eventData, GroupUserInfo.class);
                                        if(groupUserInfo!=null) {
                                            groupUserInfo.chatId = ChatInfo.toLocalChatId(groupUserInfo.chatId);
                                            TelegramManager.getTelegramManager().getTgData().putGroupNickNames(groupUserInfo.chatId,groupUserInfo.userId,groupUserInfo.nickname);
                                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_User_Nick_Name, groupUserInfo));
                                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_User_Nick_Name_GET, groupUserInfo.chatId));
                                        }
                                    }
                                }
                            }else if("messages.reaction.onUpdate".equals(actionStr)){
                                if (eventDic.has("data")) {
                                    JsonObject eventData = eventDic.getAsJsonObject("data");
                                    if (eventData != null) {
                                        MessageReactionInfo reactionInfo = new Gson().fromJson(eventData, MessageReactionInfo.class);
                                        if(reactionInfo!=null){
                                            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Update_Reaction,reactionInfo));
                                        }
                                    }

                                }

                            }
                        }
                    }
                }
            }
            return true;
        } else {
            return false;
        }
    }

    public int startIndex = 0;

    private final int tdLibCountDown = 5;

    public static final String SPU_START_INDEX = "startIndex5";

    private Disposable tdLibCountdownDisposable;
    public void startTdlibCountDown(boolean isCancleLast){
        if(isCancleLast){
            cancletdlibCountDown();
        }else{
            if(tdLibCountdownDisposable!=null&&!tdLibCountdownDisposable.isDisposed()){
                return;
            }
        }

        tdLibCountdownDisposable = Flowable.intervalRange(0, tdLibCountDown, 0, 1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .doOnComplete(new Action() {
                    @Override
                    public void run() throws Exception {
                        tdLibCountdownDisposable = null;
                        startIndex++;
                        if(startIndex>= BuildConfig.ServerHosts.length){
                            startIndex = 0;
                        }
                        SPUtils.getInstance().put(SPU_START_INDEX,startIndex);
                        reStart();
                    }
                })
                .subscribe();
    }


    public void closeTd() {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "close");
        funMap.put("@extra", rtId);
        addTask("close", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                EventBus.getDefault().register(TelegramManager.this);
//                destroy();
//                cleanCurrentData();
//                Activity activity = ActivityUtils.getTopActivity();
//                if(activity!=null) {
//                    ActivityUtils.startLauncherActivity(activity.getApplication().getPackageName());
//                }
            }
            @Override
            public void onTimeout(Map<String, Object> request) {
                destroy();
                cleanCurrentData();
                Activity activity = ActivityUtils.getTopActivity();
                if(activity!=null) {
                    ActivityUtils.finishAllActivities();
                    ActivityUtils.startLauncherActivity(activity.getApplication().getPackageName());
                }
            }
        });
    }

    private void reStart(){

        closeTd();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onTgEvent(final TgEvent tg_event) {
        if(tg_event!=null&&(tg_event.event == EUser_TgEvent.EUser_Td_Closed)){
            EventBus.getDefault().unregister(this);
            destroy();
            cleanCurrentData();
            Activity activity = ActivityUtils.getTopActivity();
            if(activity!=null) {
                ActivityUtils.finishAllActivities();
                ActivityUtils.startLauncherActivity(activity.getApplication().getPackageName());
            }

        }
    }


    public void cancletdlibCountDown(){
        if(tdLibCountdownDisposable!=null&&!tdLibCountdownDisposable.isDisposed()){
            tdLibCountdownDisposable.dispose();
        }
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="鉴权方法">
    public void setTdlibParameters(Context context, String data_directory,int dcHostIndex,TgResultBlock<TgResponse> resultBlock) {
        UserInfo.getUserInfo().data_directory = data_directory;
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("database_directory", AuthUserManager.data_directoryPath(data_directory));
        //不设置，则使用database_directory
        //paramMap.put("files_directory", "");
        paramMap.put("use_file_database", true);
        paramMap.put("use_chat_info_database", true);
        paramMap.put("use_message_database", true);
        paramMap.put("use_secret_chats", true);
        paramMap.put("api_id", 8);
        paramMap.put("api_hash", "7245de8e747a0d6fbe11f7cc14fcc0bb");
        paramMap.put("system_language_code", System.getAppLanguageEnv());
        paramMap.put("device_model", System.getModel());
        paramMap.put("application_version", System.getAppVersionName());
        paramMap.put("dc_host_idx",dcHostIndex);
        paramMap.put("dc_host_list", BuildConfig.ServerHosts);
        paramMap.put("system_version", System.getSysVersion());
        paramMap.put("enable_storage_optimizer", false);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setTdlibParameters");
        funMap.put("@extra", rtId);
        funMap.put("parameters", paramMap);
        addTask("setTdlibParameters", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                startTdlibCountDown(true);
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {

                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                startTdlibCountDown(true);
                resultBlock.onTimeout(request);
            }
        });
    }

    public void checkDatabaseEncryptionKey(Context context, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "checkDatabaseEncryptionKey");
        funMap.put("@extra", rtId);
        funMap.put("encryption_key", "");
        addTask("checkDatabaseEncryptionKey", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    public void setAuthenticationPhoneNumber(Context context, String phone, TgResultBlock<TgResponse> resultBlock) {
        setAuthenticationPhoneNumber(context,false,phone,null,null,null,null,resultBlock);
    }

    //    "isSignup":Bool 是否为注册账号
    //    "inviteCode":Int 邀请码 可选
    //    "phoneNumber":String 国际号码 可选
    //    "userName":String 用户名 可选
    //    "password":String 密码(MD5)
    public void setAuthenticationPhoneNumber(Context context,boolean isSignup, String phone,String userName, String password,String channel,String inviteCode,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setAuthenticationPhoneNumber");
        funMap.put("@extra", rtId);
        if(isSignup){
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("isSignup",isSignup);
            paramMap.put("phoneNumber",phone);
            if(!TextUtils.isEmpty(userName)){
                paramMap.put("userName",userName);
            }
            if(!TextUtils.isEmpty(password)){
                paramMap.put("password", Common.MD5(password));
            }
            try {
                if(!TextUtils.isEmpty(inviteCode)){
                    paramMap.put("inviteCode",Long.parseLong(inviteCode));
                }
            }catch (Exception e){
                if(!TextUtils.isEmpty(inviteCode)){
                    paramMap.put("inviteCode",inviteCode);
                }
            }
            try {
                if(!TextUtils.isEmpty(channel)){
                    paramMap.put("channelId",Long.parseLong(channel));
                }
            }catch (Exception e){
                if(!TextUtils.isEmpty(channel)){
                    paramMap.put("channelId",channel);
                }
            }
            funMap.put("phone_number", new Gson().toJson(paramMap));
        }else{
            funMap.put("phone_number", phone);
        }
        addTask("setAuthenticationPhoneNumber", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorCode(response), errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void checkAuthenticationCode(Context context, String code, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "checkAuthenticationCode");
        funMap.put("@extra", rtId);
        funMap.put("code", code);
        addTask("checkAuthenticationCode", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorCode(response), errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void registerUser(Context context, String firstName, String lastName, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "registerUser");
        funMap.put("@extra", rtId);
        funMap.put("first_name", firstName);
        funMap.put("last_name", lastName);
        addTask("registerUser", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="消息解析">
    public static void parseMessageContent(JsonObject contentDic, MessageInfo msg) {
        if (contentDic != null) {
            String type = contentDic.get("@type").getAsString();
            if ("messageText".equals(type)) {
                msg.messageType = MessageType.MessageType_Text;
                JsonObject textDic = contentDic.getAsJsonObject("text");
                if (textDic != null && textDic.has("text")) {
                    msg.textTypeContent = textDic.get("text").getAsString();
                    if(textDic.has("web_page")){
                        HtmlDocumentInfo documentInfo = new HtmlDocumentInfo();
                        msg.setHtmlDocumentInfo(documentInfo);
                        JsonObject web_page = textDic.get("web_page").getAsJsonObject();
                        if(web_page!=null){
                            documentInfo.setDisplay_url(web_page.get("display_url").getAsString());
                            documentInfo.setTitle(web_page.get("title").getAsString());
                            if(web_page.has("description")){
                                JsonObject description = web_page.get("description").getAsJsonObject();
                                if(description!=null){
                                    documentInfo.setContent(description.get("text").getAsString());
                                }
                            }
                            if(web_page.has("photo")){
                                JsonObject photo = web_page.get("photo").getAsJsonObject();
                            }
                        }
                    }

                }
                try {
                    msg.parseTextToExMessage();
                } catch (Exception e) {
                    Constants.Loge(TAG, e.getLocalizedMessage());
                }
            } else if ("messageAnimation".equals(type)) {
                msg.messageType = MessageType.MessageType_Animation;
            } else if ("messageAudio".equals(type)) {
                msg.messageType = MessageType.MessageType_Audio;
            } else if ("messageVoiceNote".equals(type)) {
                msg.messageType = MessageType.MessageType_Voice_Note;
            } else if ("messageDocument".equals(type)) {
                msg.messageType = MessageType.MessageType_Document;
                if (msg.content != null && msg.content.document != null) {
                    //解析标题
                    String fileTitle = null;
                    if (contentDic.has("caption")) {//真实标题
                        JsonObject textDic = contentDic.getAsJsonObject("caption");
                        if (textDic != null && textDic.has("text")) {
                            fileTitle = textDic.get("text").getAsString();
                        }
                    }
                    if (StringUtils.isEmpty(fileTitle)) {//原文件名称
                        fileTitle = msg.content.document.file_name;
                    }
                    if (StringUtils.isEmpty(fileTitle)) {//默认值
                        fileTitle = "未知文件名";
                    }
                    msg.content.title = fileTitle;
                }
            } else if ("messagePhoto".equals(type)) {
                msg.messageType = MessageType.MessageType_Photo;
            } else if ("messagePinMessage".equals(type)) {
                msg.messageType = MessageType.MessageType_Pinned;
            } else if ("messageSticker".equals(type)) {
                msg.messageType = MessageType.MessageType_Sticker;
            } else if ("messageVideo".equals(type)) {
                msg.messageType = MessageType.MessageType_Video;
            } else if ("messagePoll".equals(type)) {
                msg.messageType = MessageType.MessageType_Poll;
            } else if ("messageLocation".equals(type)) {
                msg.messageType = MessageType.MessageType_Location;
            } else if ("messageCall".equals(type)) {
                msg.messageType = MessageType.MessageType_Call;
            } else if("messageContact".equals(type)){
                msg.messageType = MessageType.MessageType_Contact;
            } else if("messageContactRegistered".equals(type)){
                msg.messageType = MessageType.MessageType_Contact_Registered;
            }else {
                msg.messageType = MessageType.MessageType_Unkown;
            }
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="会话相关">

    /**
     * 重要，获取会话列表第一个触发api
     * 通过获取会话ids,触发一系列update动作,可以分页，也可以不分页，为逻辑简单，设置阀值2000条
     *
     * @param resultBlock
     */
    public void getChatListIds(Context context, TgResultBlock<Object> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("@type", "chatListMain");
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getChats");
        funMap.put("chat_list", paramMap);
        funMap.put("offset_order", Long.MAX_VALUE);
        funMap.put("offset_chat_id", 0);
        funMap.put("limit", 2000);
        funMap.put("@extra", rtId);
        addTask("getChatListIds", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                resultBlock.onResult(request, response, obj);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getChatMessageCount(Context context, long chatId,TgResultBlock<Integer> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("@type", "searchMessagesFilterUnreadMention");
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getChatMessageCount");
        funMap.put("filter", paramMap);
        funMap.put("chat_id", chatId);
        funMap.put("return_local",false);
        funMap.put("@extra", rtId);
        addTask("getChatMessageCount", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                resultBlock.onResult(request, response, (response.get("count") == null)?0:response.get("count").getAsInt());
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onResult(request,null,0);
            }
        });
    }

    /**
     * 根据关键字搜索会话
     *
     * @param keyword     关键字，不可以为空
     * @param resultBlock 回调，返回Chatid集合
     * @return 任务id，可以通过cancelTask(int rtId)结束请求任务（键盘输入触发搜索比较频繁，开始下一次搜索前，先结束请求的任务）
     */
    public int searchPublicChatsList(Context context, String keyword, TgResultBlock<List<Long>> resultBlock) {
        if (StringUtils.isEmpty(keyword)) {
            return 0;
        }
        if (!getTgData().isValid()) {
            return 0;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "searchPublicChats");
        funMap.put("query", keyword);
        funMap.put("@extra", rtId);
        addTask("searchPublicChatsList", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<Long> ids = null;
                if (response != null && response.has("chat_ids")) {
                    if (!isResultError(response)) {
                        JsonArray chatids = response.getAsJsonArray("chat_ids");
                        if (chatids != null) {
                            ids = new Gson().fromJson(chatids, new TypeToken<List<Long>>() {
                            }.getType());
                        }
                    }
                }
                resultBlock.onResult(request, response, ids);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
        return rtId;
    }


    public void createNewSecretChat(Context context, long userId, TgResultBlock<ChatInfo> resultBlock) {
        List<ChatInfo> list = TelegramManager.getTelegramManager().getTgData().getChatList();
        if(!Common.isEmpty(list)){
            for(ChatInfo chatInfo:list){
                if(chatInfo.order>0&&chatInfo.isSecretChat()&&chatInfo.userId() == userId){
                    if(resultBlock!=null){
                        resultBlock.onResult(null,null,chatInfo);
                    }
                    return;
                }
            }
        }
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "createNewSecretChat");
        funMap.put("user_id", userId);
        funMap.put("@extra", rtId);
        addTask("searchPublicChatsList", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                ChatInfo chatInfo = null;
                try {
                    chatInfo = new Gson().fromJson(response, ChatInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, chatInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
        return;
    }

    public int searchMyChatsList(Context context, String keyword, TgResultBlock<List<Long>> resultBlock) {
        if (StringUtils.isEmpty(keyword)) {
            return 0;
        }
        if (!getTgData().isValid()) {
            return 0;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "searchChats");
        funMap.put("query", keyword);
        funMap.put("limit", Integer.MAX_VALUE);
        funMap.put("@extra", rtId);
        addTask("searchPublicChatsList", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<Long> ids = null;
                if (response != null && response.has("chat_ids")) {
                    if (!isResultError(response)) {
                        JsonArray chatids = response.getAsJsonArray("chat_ids");
                        if (chatids != null) {
                            ids = new Gson().fromJson(chatids, new TypeToken<List<Long>>() {
                            }.getType());
                        }
                    }
                }
                resultBlock.onResult(request, response, ids);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
        return rtId;
    }


    public int searchChatsList(Context context, String keyword, TgResultBlock<List<Long>> resultBlock) {
        if (StringUtils.isEmpty(keyword)) {
            return 0;
        }
        if (!getTgData().isValid()) {
            return 0;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "searchContacts");
        funMap.put("query", keyword);
        funMap.put("limit", Integer.MAX_VALUE);
        funMap.put("@extra", rtId);
        addTask("searchContacts", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<Long> ids = null;
                if (response != null && response.has("user_ids")) {
                    if (!isResultError(response)) {
                        JsonArray chatids = response.getAsJsonArray("user_ids");
                        if (chatids != null) {
                            ids = new Gson().fromJson(chatids, new TypeToken<List<Long>>() {
                            }.getType());
                        }
                    }
                }
                resultBlock.onResult(request, response, ids);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
        return rtId;
    }

    /**
     * 会话设置是否提醒
     *
     * @param chatId                会话id
     * @param isDisableNotification 是否禁用提醒
     * @param resultBlock           回调
     */
    public void toggleChatDisableNotification(Context context, long chatId, boolean isDisableNotification, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "toggleChatDefaultDisableNotification");
        funMap.put("chat_id", chatId);
        funMap.put("default_disable_notification", isDisableNotification);
        funMap.put("@extra", rtId);
        addTask("toggleChatDisableNotification", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 会话设置置顶
     *
     * @param chatId      会话id
     * @param isPinned    是否置顶
     * @param resultBlock 回调
     */
    public void toggleChatIsPinned(Context context, long chatId, boolean isPinned, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("@type", "chatListMain");
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "toggleChatIsPinned");
        funMap.put("chat_id", chatId);
        funMap.put("chat_list", paramMap);
        funMap.put("is_pinned", isPinned);
        funMap.put("@extra", rtId);
        addTask("toggleChatIsPinned", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 清空会话并删除
     *
     * @param chatId       会话id
     * @param isDeleteChat 是否删除会话
     * @param resultBlock  回调
     */
    public void deleteChatHistory(Context context, long chatId, boolean isDeleteChat, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "deleteChatHistory");
        funMap.put("chat_id", chatId);
        funMap.put("remove_from_chat_list", isDeleteChat);
        funMap.put("@extra", rtId);
        addTask("deleteChatHistory", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(resultBlock!=null){
                    if (isResultError(response)) {
                        resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                    } else {
                        resultBlock.onResult(request, response, new TgResponse(true, ""));
                    }
                }

            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                if(resultBlock!=null){
                    resultBlock.onTimeout(request);
                }
            }
        });
    }

    /**
     * 创建单聊会话
     *
     * @param userId      用户id
     * @param resultBlock 回调，返回chatinfo
     */
    public void createPrivateChat(Context context, long userId, TgResultBlock<ChatInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "createPrivateChat");
        funMap.put("user_id", userId);
        funMap.put("force", true);
        funMap.put("@extra", rtId);
        addTask("createPrivateChat", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(resultBlock==null){
                    return;
                }
                if (isResultError(response)) {
                    String errorStr = errorMsg(response);
                    if("6_Chat info not found".equals(errorStr)){
                        errorStr = "用户不存在";
                    }
                    ToastUtils.showShort(errorStr);
                    resultBlock.onResult(request, response, null);
                } else {
                    ChatInfo chat = new Gson().fromJson(response, ChatInfo.class);
                    resultBlock.onResult(request, response, chat);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                if(resultBlock==null){
                    return;
                }
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 创建超级群组
     *
     * @param membersList 成员列表，至少2个用户
     * @param resultBlock 回调
     */
    public void createSuperGroupChat(Context context, List<UserInfo> membersList, TgResultBlock<TgResponse> resultBlock) {
        if (membersList == null || membersList.size() < 2) {
            resultBlock.onResult(null, null, new TgResponse(false, "请至少选择2位好友"));
            return;
        }
        if (!getTgData().isValid()) {
            return;
        }
        //群组名称
        String groupName;
        if (membersList.size() > 2) {
            groupName = String.format("%s、%s、%s", membersList.get(0).displayName(), membersList.get(1).displayName(), membersList.get(2).displayName());
        } else {
            groupName = String.format("%s、%s、%s", membersList.get(0).displayName(), membersList.get(1).displayName(), UserInfo.getUserInfo().displayName());
        }
        //创建群组
        createSuperGroupChat(context, groupName, new TgResultBlock<ChatInfo>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, ChatInfo chat) {
                if (isActivityDestroy(context)) return;
                if (chat != null) {
                    List<Long> ids = new ArrayList<>();
                    for (UserInfo user : membersList) {
                        ids.add(user.id);
                    }
                    addMembers2SuperGroup(context, chat.id, ids, new TgResultBlock<TgResponse>() {
                        @Override
                        public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {
                            resultBlock.onResult(request, response, new TgResponse(true, 200, null, chat));
                        }

                        @Override
                        public void onTimeout(Map<String, Object> request) {
                            resultBlock.onTimeout(request);
                        }
                    });
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    private void createSuperGroupChat(Context context, String groupName, TgResultBlock<ChatInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "createNewSupergroupChat");
        funMap.put("title", groupName);
        funMap.put("is_channel", false);
        funMap.put("@extra", rtId);
        addTask("createSuperGroupChat", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    ChatInfo chat = new Gson().fromJson(response, ChatInfo.class);
                    resultBlock.onResult(request, response, chat);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void searchPublicChats(Context context, int offset,int limit,TgResultBlock<List<Long>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("ver",1);
        queryMap.put("offset",offset);
        queryMap.put("limit",limit);

        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "searchPublicChats");
        funMap.put("query",new Gson().toJson(queryMap));
        funMap.put("@extra", rtId);
        addTask("searchPublicChats", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isActivityDestroy(context)) return;
                List<Long> ids = null;
                if (response != null && response.has("chat_ids")) {
                    if (!isResultError(response)) {
                        JsonArray chatids = response.getAsJsonArray("chat_ids");
                        if (chatids != null) {
                            ids = new Gson().fromJson(chatids, new TypeToken<List<Long>>() {
                            }.getType());
                        }
                    }
                }
                resultBlock.onResult(request, response, ids);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void searchChatsNearby(Context context, AMapLocation location, TgResultBlock<ChatsNearbyInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> locationMap = new HashMap<>();
        locationMap.put("latitude",location.getLatitude());
        locationMap.put("longitude",location.getLongitude());
//        locationMap.put("latitude",27.782709);
//        locationMap.put("longitude",120.663898);
        locationMap.put("horizontal_accuracy",100000);

        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "searchChatsNearby");
        funMap.put("location", locationMap);
        funMap.put("@extra", rtId);
        addTask("createSuperGroupChat", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    ChatsNearbyInfo nearbyInfo = new Gson().fromJson(response, ChatsNearbyInfo.class);
                    resultBlock.onResult(request, response, nearbyInfo);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    // </editor-fold>


    // <editor-fold defaultstate="collapsed" desc="标签">
    public void getFavoriteStickers(Context context, TgResultBlock<List<StickerInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getSavedAnimations");
        funMap.put("@extra", rtId);
        addTask("getSavedAnimations", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<StickerInfo> stickerInfos = new ArrayList<>();
                if (response != null && response.has("animations")) {
                    if (!isResultError(response)) {
                        JsonArray list = response.getAsJsonArray("animations");
                        if (list != null && list.size() > 0) {
                            for (int i = 0; i < list.size(); i++) {
                                JsonObject messageDic = list.get(i).getAsJsonObject();
                                StickerInfo stickerInfo = new Gson().fromJson(messageDic, StickerInfo.class);
                                stickerInfos.add(0, stickerInfo);
                            }
                        }
                    }
                }
                resultBlock.onResult(request, response, stickerInfos);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void getRemoteStickerById(Context context,String remoteFileId, TgResultBlock<StickerInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> fileType = new HashMap<>();
        fileType.put("@type", "fileTypeAnimation");
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getRemoteFile");
        funMap.put("remote_file_id",remoteFileId);
        funMap.put("file_type",fileType);
        funMap.put("@extra", rtId);
        addTask("getSavedAnimations", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                StickerInfo stickerInfo = null;
                if (response != null) {
                    stickerInfo = new Gson().fromJson(response, StickerInfo.class);
                }
                resultBlock.onResult(request, response, stickerInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void addFavoriteSticker(Context context, String remoteFileId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        Map<String, Object> stickerDic = new HashMap<>();
        stickerDic.put("@type", "inputFileRemote");
        stickerDic.put("id", remoteFileId);
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "addSavedAnimation");
        funMap.put("animation", stickerDic);
        funMap.put("@extra", rtId);
        addTask("addSavedAnimation", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {

                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void removeFavoriteSticker(Context context, String remoteFileId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> stickerDic = new HashMap<>();
        stickerDic.put("@type", "inputFileRemote");
        stickerDic.put("id", remoteFileId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "removeSavedAnimation");
        funMap.put("animation", stickerDic);
        funMap.put("@extra", rtId);
        addTask("removeFavoriteSticker", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {

                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="消息相关">

    public void getRealChatMessageList(Context context, long chatId, long from_message_id, int offset, int limit, TgResultBlock<List<MessageInfo>> resultBlock) {
        getChatMessageList(context, chatId, from_message_id, offset, limit, new TgResultBlock<List<MessageInfo>>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, List<MessageInfo> obj) {
                if (isActivityDestroy(context)) return;
                if (from_message_id==0 && !Common.isEmpty(obj) ) {
                    getRealChatMessageList(context, chatId, obj.get(obj.size()-1).id, offset, limit, new TgResultBlock<List<MessageInfo>>() {
                        @Override
                        public void onResult(Map<String, Object> reRequest, JsonObject reResponse, List<MessageInfo> reObj) {
                            if(!Common.isEmpty(reObj)){
                                reObj.add(obj.get(obj.size()-1));
                                resultBlock.onResult(request, response, reObj);
                            }else{
                                resultBlock.onResult(request, response, obj);
                            }
                        }

                        @Override
                        public void onTimeout(Map<String, Object> reRequest) {
                            resultBlock.onResult(request, response, obj);
                        }
                    });
                } else {
                    resultBlock.onResult(request, response, obj);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取消息历史记录，直接返回MessageInfo列表，按时间由小到大排序
     * 首次进入聊天页面时，必须调用两次，第一次可能只会获取1条消息，因为td库没有把消息加载到内存，连续调用间隔可以很短，比如：100/200ms
     *
     * @param chatId          会话id
     * @param from_message_id 从哪条消息返回，页面显示时，请避免from_message_id这条消息重复显示；如果是0，则从最新的消息开始返回
     * @param offset          偏移量，如果为0，则从from_message_id为起点，如果为负数，则从from_message_id+N开始，如果为正数，则从from_message_id-N开始，具体用数据来验证确认
     * @param limit           限制条数
     * @param resultBlock     回调
     */
    public void getChatMessageList(Context context, long chatId, long from_message_id, int offset, int limit, TgResultBlock<List<MessageInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getChatHistory");
        funMap.put("chat_id", chatId);
        funMap.put("from_message_id", from_message_id);
        funMap.put("offset", offset);
        funMap.put("limit", limit);
        funMap.put("only_local", false);
        funMap.put("@extra", rtId);
        addTask("getChatMessageList", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<MessageInfo> messages = new ArrayList<>();
                if (response != null && response.has("messages")) {
                    if (!isResultError(response)) {
                        JsonArray list = response.getAsJsonArray("messages");
                        if (list != null && list.size() > 0) {
                            for (int i = 0; i < list.size(); i++) {
                                JsonObject messageDic = list.get(i).getAsJsonObject();
                                MessageInfo msg = new Gson().fromJson(messageDic, MessageInfo.class);
                                parseMessageContent(messageDic.getAsJsonObject("content"), msg);
                                messages.add(0, msg);
                            }
                        }
                    }
                }
                resultBlock.onResult(request, response, messages);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void searchChatMessages(Context context, long chatId, SearchMessagesFilter filters, long from_message_id, String query,int offset, int limit, TgResultBlock<List<MessageInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "searchChatMessages");
        funMap.put("chat_id", chatId);
        funMap.put("from_message_id", from_message_id);
        funMap.put("offset", offset);
        funMap.put("limit", limit);
        funMap.put("filter", filters);
        funMap.put("query",query);
        funMap.put("@extra", rtId);
        addTask("searchChatMessages", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<MessageInfo> messages = new ArrayList<>();
                if (response != null && response.has("messages")) {
                    if (!isResultError(response)) {
                        JsonArray list = response.getAsJsonArray("messages");
                        if (list != null && list.size() > 0) {
                            for (int i = 0; i < list.size(); i++) {
                                JsonObject messageDic = list.get(i).getAsJsonObject();
                                MessageInfo msg = new Gson().fromJson(messageDic, MessageInfo.class);
                                parseMessageContent(messageDic.getAsJsonObject("content"), msg);
                                messages.add(msg);
                            }
                        }
                    }
                }
                resultBlock.onResult(request, response, messages);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 根据关键字搜索消息
     *
     * @param keyword     关键字，不可以为空
     * @param resultBlock 回调
     * @return 任务id，可以通过cancelTask(int rtId)结束请求任务（键盘输入触发搜索比较频繁，开始下一次搜索前，先结束请求的任务）
     */
    public int searchMessagesList(Context context, String keyword, TgResultBlock<List<MessageInfo>> resultBlock) {
        if (StringUtils.isEmpty(keyword)) {
            return 0;
        }
        if (!getTgData().isValid()) {
            return 0;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("@type", "chatListMain");
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "searchMessages");
        funMap.put("chat_list", paramMap);
        funMap.put("query", keyword);
        funMap.put("limit", 20);
        funMap.put("@extra", rtId);
        addTask("searchMessagesList", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<MessageInfo> messages = new ArrayList<>();
                if (response != null && response.has("messages")) {
                    if (!isResultError(response)) {
                        JsonArray list = response.getAsJsonArray("messages");
                        if (list != null && list.size() > 0) {
                            for (int i = 0; i < list.size(); i++) {
                                JsonObject messageDic = list.get(i).getAsJsonObject();
                                MessageInfo msg = new Gson().fromJson(messageDic, MessageInfo.class);
                                parseMessageContent(messageDic.getAsJsonObject("content"), msg);
                                messages.add(0, msg);
                            }
                        }
                    }
                }
                resultBlock.onResult(request, response, messages);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
        return rtId;
    }

    /**
     * 发送文本消息，会触发以下3个事件
     * EUser_Td_Chat_New_Message,//新消息 data = MessageInfo
     * EUser_Td_Chat_Send_Message_Success,//发送成功 data = MessageInfo, dataEx = Long, old_message_id
     * EUser_Td_Chat_Send_Message_Fail,//发送失败 data = MessageInfo, dataEx = Long, old_message_id
     *
     * @param chatId      会话id
     * @param text        文本内容
     * @param resultBlock 回调
     */
    public void sendTextMessage(Context context, long chatId, String text, TgResultBlock<TgResponse> resultBlock) {
        sendTextMessage(context,chatId,text,0,resultBlock);
    }

    public void getWebPagePreview(Context context, String text,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();

        Map<String, Object> textDic = new HashMap<>();
        textDic.put("@type", "formattedText");
        textDic.put("text", text);
        textDic.put("entities", new ArrayList<>());
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getWebPagePreview");
        funMap.put("text", textDic);
        funMap.put("@extra", rtId);
        addTask("getWebPagePreview", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {

                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void handleChat(Context context, long chatId,boolean isOpen,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", isOpen?"openChat":"closeChat");
        funMap.put("chat_id", chatId);
        funMap.put("@extra", rtId);
        addTask("handleChat", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public String sendBurnAfterReadMessage(String text,int countDown) {
        return MessageInfo.getTextExMessage(GsonUtils.toJson(new BurnAfterReadInfo(text,countDown)), BurnAfterRead_MessageType, BurnAfterRead_MessageType_Done);
    }

    public void sendTextMessage(Context context, long chatId, String text, long replyMessageId, TgResultBlock<TgResponse> resultBlock) {
        sendTextMessage(context,chatId,text,replyMessageId,null,resultBlock);
    }

    public void sendTextMessage(Context context, long chatId, String text, long replyMessageId, List<TextEntity> textEntities, TgResultBlock<TgResponse> resultBlock){
        sendTextMessage(context,chatId,text,replyMessageId,textEntities,-1,resultBlock);
    }

    public void sendTextMessage(Context context, long chatId, String text, long replyMessageId, List<TextEntity> textEntities, int countDown,TgResultBlock<TgResponse> resultBlock) {
        sendTextMessage(context,chatId,text,replyMessageId,textEntities,countDown,false,resultBlock);
    }

    public Map<String,Object> buildTextMessageContent(String text, List<TextEntity> textEntities){
        Map<String, Object> textDic = new HashMap<>();
        textDic.put("@type", "formattedText");
        textDic.put("text", text);
        if(textEntities!=null&&textEntities.size()>0){
            textDic.put("entities", textEntities);
        }else{
            textDic.put("entities", new ArrayList<>());
        }
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageText");
        messageText.put("text", textDic);
        messageText.put("disable_web_page_preview", false);
        messageText.put("clear_draft", false);
        return messageText;
    }

    public void sendTextMessage(Context context, long chatId, String text, long replyMessageId, List<TextEntity> textEntities, int countDown,boolean hasAdPermission,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        Pair<String,ReplyMarkupInfo> pair = null;
        if(hasAdPermission){
            pair = getReplyMarkupByText(text);
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> messageText = buildTextMessageContent(pair==null?text:pair.first,textEntities);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", messageText);
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        if(pair!=null){
            funMap.put("reply_markup", pair.second);
        }
        funMap.put("@extra", rtId);
        if(replyMessageId>0){
            funMap.put("reply_to_message_id", replyMessageId);
        }
        Log.e("sendTextMessageParam",new Gson().toJson(funMap));
        addTask("sendTextMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {

                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void sendMessageAlbum(Context context, long chatId, long replyMessageId, int countDown, List<Map<String,Object>> inputMessageContents, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessageAlbum");
        funMap.put("chat_id", chatId);
        funMap.put("input_message_contents", inputMessageContents);
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        funMap.put("@extra", rtId);
        if(replyMessageId>0){
            funMap.put("reply_to_message_id", replyMessageId);
        }
        addTask("sendMessageAlbum", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {

                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public static final String URL_PATTERN_STR = "http[s]*://[^\\]]*";
    public static final Pattern DEFAULT_URL_PATTERN = Pattern.compile(URL_PATTERN_STR.trim());
    public static final String AD_PATTERN_STR = "\\[[^\\[]\\S*?(:|：)http[s]*://[^\\]]*\\]";
    public static final Pattern DEFAULT_AD_PATTERN = Pattern.compile(AD_PATTERN_STR);



    public static Pair<String, ReplyMarkupInfo> getReplyMarkupByText(String text){
        if(TextUtils.isEmpty(text)){
            return null;
        }
        Matcher matcher = DEFAULT_AD_PATTERN.matcher(text);
        List<List<InlineKeyboardButton>> rows = null;
        int count = 0;
        while (matcher.find()){
            String value = matcher.group();
            Matcher urlMatcher = DEFAULT_URL_PATTERN.matcher(value);
            if(urlMatcher.find()){
                String url = urlMatcher.group();
                String content = value.substring(1,urlMatcher.start()-1);
                if(rows==null){
                    rows = new ArrayList<>();
                }
                InlineKeyboardButton button = new InlineKeyboardButton(content,url);
                if(count%2==0){
                    List<InlineKeyboardButton> buttons = new ArrayList<>();
                    buttons.add(button);
                    rows.add(buttons);
                }else{
                    List<InlineKeyboardButton> buttons = rows.get(rows.size()-1);
                    if(buttons!=null){
                        buttons.add(button);
                    }
                }
                count++;
            }
        }
        if(rows == null){
            return null;
        }
        return new Pair<String,ReplyMarkupInfo>(text.replaceAll(AD_PATTERN_STR,""),new ReplyMarkupInfo("replyMarkupInlineKeyboard",rows));
    }

    private String transferErrorMsg(String errorMsg){
        if(TextUtils.isEmpty(errorMsg)){
            return "";
        }
        if(errorMsg.contains("400_Not enough rights")){
            return "无权限发送";
        }else{
            return errorMsg;
        }
    }

    private Map<String,String> qrcodeCache = new HashMap<>();

    public boolean haveQrCodeByFilePath(String filePath){
        if(TextUtils.isEmpty(filePath)){
            return false;
        }
        return qrcodeCache.containsKey(filePath);
    }

    public String getQrCodeByFilePath(String filePath){
        if(TextUtils.isEmpty(filePath)){
            return null;
        }
        return qrcodeCache.get(filePath);
    }

    public String putQrCodeByFilePath(String filePath,Bitmap bitmap){
        if(TextUtils.isEmpty(filePath)||bitmap == null){
            return null;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int[] pixels = new int[width * height];
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
        RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
        BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
        Reader reader = new QRCodeReader();
        Result result = null;
        try {
            result = reader.decode(binaryBitmap);
        } catch (NotFoundException | ChecksumException | FormatException e) {
            e.printStackTrace();
        }
        if(result!=null&&!TextUtils.isEmpty(result.getText())){
            qrcodeCache.put(filePath,result.getText());
            return result.getText();
        }
        return null;
    }



    /**
     * 发送Pin文本消息，会触发以下3个事件
     * EUser_Td_Chat_New_Message,//新消息 data = MessageInfo
     * EUser_Td_Chat_Send_Message_Success,//发送成功 data = MessageInfo, dataEx = Long, old_message_id
     * EUser_Td_Chat_Send_Message_Fail,//发送失败 data = MessageInfo, dataEx = Long, old_message_id
     *
     * @param chatId      会话id
     * @param text        文本内容
     * @param resultBlock 回调 - 返回发送的消息
     */
    public void sendPinTextMessage(Context context, long chatId, String text, TgResultBlock<MessageInfo> resultBlock) {
        sendTextMessage(context, chatId, text, new TgResultBlock<TgResponse>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    MessageInfo msg = new Gson().fromJson(response, MessageInfo.class);
                    parseMessageContent(response.getAsJsonObject("content"), msg);
                    resultBlock.onResult(request, response, msg);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void resendMessages(Context context, long chatId, List<Long> message_ids, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "resendMessages");
        funMap.put("chat_id", chatId);
        funMap.put("message_ids", message_ids);
        funMap.put("@extra", rtId);
        addTask("resendMessages", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * sendPinTextMessage发送后拿到的pinMsgId作为入参(sendPinTextMessage必须发送成功后，拿到服务器messageid才可以)，设置公告
     *
     * @param chatId      会话公告
     * @param pinMsgId    pin消息id
     * @param resultBlock 回调
     */
    public void setGroupNotice(Context context, long chatId, long pinMsgId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "pinChatMessage");
        funMap.put("chat_id", chatId);
        funMap.put("message_id", pinMsgId);
        funMap.put("disable_notification", false);
        funMap.put("@extra", rtId);
        addTask("setGroupNotice", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 群简介
     */
    public void setChatDescription(Context context, long chatId, String description, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatDescription");
        funMap.put("chat_id", chatId);
        funMap.put("description", description);
        funMap.put("@extra", rtId);
        addTask("setGroupNotice", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取群组公告
     *
     * @param chatId      会话id
     * @param resultBlock 返回一条pin文本消息，表示群组公告
     */
    public void getGroupNotice(Context context, long chatId, TgResultBlock<MessageInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getChatPinnedMessage");
        funMap.put("chat_id", chatId);
        funMap.put("@extra", rtId);
        addTask("getGroupNotice", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    MessageInfo msg = new Gson().fromJson(response, MessageInfo.class);
                    parseMessageContent(response.getAsJsonObject("content"), msg);
                    resultBlock.onResult(request, response, msg);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 发送图片消息，会触发以下3个事件
     * EUser_Td_Chat_New_Message,//新消息 data = MessageInfo
     * EUser_Td_Chat_Send_Message_Success,//发送成功 data = MessageInfo, dataEx = Long, old_message_id
     * EUser_Td_Chat_Send_Message_Fail,//发送失败 data = MessageInfo, dataEx = Long, old_message_id
     *
     * @param chatId      会话id
     * @param localPath   本地图片路径
     * @param width       图片宽
     * @param height      图片高
     * @param resultBlock 回调
     */
    public void sendPhotoMessage(Context context, long chatId, String localPath, int width, int height, int countDown,TgResultBlock<TgResponse> resultBlock) {
        sendPhotoMessage(context,chatId, buildLocalPhotoMessageContent(localPath,width,height,null),countDown,null,resultBlock);
    }

    public Map<String, Object> buildLocalPhotoMessageContent(String localPath, int width, int height, FormatTextInfo caption){
        Map<String, Object> photoDic = new HashMap<>();
        photoDic.put("@type", "inputFileLocal");
        photoDic.put("path", localPath);
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessagePhoto");
        messageText.put("photo", photoDic);
        messageText.put("width", width);
        messageText.put("height", height);
        messageText.put("caption",caption);

        AppConfigInfo info = AppConfigInfo.getAppWithoutLoginConfigInfo();
        if (info != null&&!info.using_oss) {
            return messageText;
        }
        Map<String, Object> messageOss = new HashMap<>();
        messageOss.put("@type", "inputMessageOss");
        messageOss.put("resource", messageText);
        return messageOss;
    }

    public void sendPhotoMessage(Context context, long chatId, String fileId, float width, float height, int countDown,TgResultBlock<TgResponse> resultBlock) {
        Map<String, Object> photoDic = new HashMap<>();
        photoDic.put("@type", "inputFileRemote");
        photoDic.put("id", fileId);
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessagePhoto");
        messageText.put("photo", photoDic);
        messageText.put("width", (int)width);
        messageText.put("height", (int)height);
        sendPhotoMessage(context,chatId,messageText,countDown,null,resultBlock);
    }

    public static Map<String, Object> buildRemoteDic(String fileId){
        Map<String, Object> photoDic = new HashMap<>();
        photoDic.put("@type", "inputFileRemote");
        photoDic.put("id", fileId);
        return photoDic;
    }



    public void sendPhotoMessage(Context context, long chatId, Map<String,Object> messageText, int countDown,ReplyMarkupInfo info,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        if(info!=null){
            funMap.put("reply_markup", info);
        }
        funMap.put("@type", "sendMessage");
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", messageText);
        funMap.put("@extra", rtId);
        addTask("sendPhotoMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void sendContactMessage(Context context, long chatId,UserInfo userInfo,int countDown, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> phoneMap = new HashMap<>();
        phoneMap.put("userId", userInfo.id);
        Map<String, Object> contact = new HashMap<>();
//        contact.put("phone_number", "8618938901487");
        contact.put("phone_number", GsonUtils.toJson(phoneMap));
        contact.put("first_name", userInfo.raw_first_name);
        contact.put("last_name", userInfo.raw_last_name);
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageContact");
        messageText.put("contact", contact);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", messageText);
        funMap.put("@extra", rtId);
        addTask("sendContactMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void sendRemoteGifMessage(Context context, long chatId, String remoteFileId, int width, int height, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> photoDic = new HashMap<>();
        photoDic.put("@type", "inputFileRemote");
        photoDic.put("path", remoteFileId);
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageAnimation");
        messageText.put("animation", photoDic);
        messageText.put("width", width);
        messageText.put("height", height);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", messageText);
        funMap.put("@extra", rtId);
        addTask("sendGifMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void sendGifMessage(Context context, long chatId, String localPath, int width, int height,int countDown, TgResultBlock<TgResponse> resultBlock) {
        Map<String, Object> photoDic = new HashMap<>();
        photoDic.put("@type", "inputFileLocal");
        photoDic.put("path", localPath);
        sendGifMessage(context,chatId,photoDic,width,height,countDown,resultBlock);
    }

    public void sendGifMessage(Context context, long chatId, Map<String, Object> photoDic, int width, int height,int countDown, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();

        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageAnimation");
        messageText.put("animation", photoDic);
        messageText.put("width", width);
        messageText.put("height", height);
//        Map<String, Object> messageContent = new HashMap<>();
//        messageContent.put("@type", "inputMessageOss");
//        messageContent.put("resource", messageText);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", messageText);
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        funMap.put("@extra", rtId);
        addTask("sendGifMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void sendStickerGifMessage(Context context, long chatId, String remoteFileId, int width, int height, int countDown,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> photoDic = new HashMap<>();
        photoDic.put("@type", "inputFileRemote");
        photoDic.put("id", remoteFileId);
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageAnimation");
        messageText.put("animation", photoDic);
        messageText.put("width", width);
        messageText.put("height", height);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", messageText);
        funMap.put("@extra", rtId);
        addTask("sendGifMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 发送视频消息，会触发以下3个事件
     * EUser_Td_Chat_New_Message,//新消息 data = MessageInfo
     * EUser_Td_Chat_Send_Message_Success,//发送成功 data = MessageInfo, dataEx = Long, old_message_id
     * EUser_Td_Chat_Send_Message_Fail,//发送失败 data = MessageInfo, dataEx = Long, old_message_id
     *
     * @param chatId         会话id
     * @param localCoverPath 本地封面路径- 目前不支持，直接传null即可
     * @param localVideoPath 本地视频路径
     * @param width          视频宽
     * @param height         视频高
     * @param duration       视频时长，秒
     * @param resultBlock    回调
     */
    public void sendVideoMessage(Context context, long chatId, String localCoverPath, String localVideoPath, int width, int height, long duration, int countDown,TgResultBlock<TgResponse> resultBlock) {
        Map<String, Object> videoDic = new HashMap<>();
        videoDic.put("@type", "inputFileLocal");
        videoDic.put("path", localVideoPath);
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageVideo");
        messageText.put("video", videoDic);
        messageText.put("width", width);
        messageText.put("height", height);
        messageText.put("duration", duration);
        AppConfigInfo info = AppConfigInfo.getAppWithoutLoginConfigInfo();
        if (info != null&&!info.using_oss) {
            sendVideoMessage(context,chatId,messageText,countDown,resultBlock);
            return;
        }
        Map<String, Object> messageContent = new HashMap<>();
        messageContent.put("@type", "inputMessageOss");
        messageContent.put("resource", messageText);

    }


    public void sendVideoMessage(Context context, long chatId, String fileId, float width, float height, long duration, int countDown,TgResultBlock<TgResponse> resultBlock) {
        Map<String, Object> videoDic = new HashMap<>();
        videoDic.put("@type", "inputFileRemote");
        videoDic.put("id", fileId);
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageVideo");
        messageText.put("video", videoDic);
        messageText.put("width", (int)width);
        messageText.put("height", (int)height);
        messageText.put("duration", duration);
        sendVideoMessage(context,chatId,messageText,countDown,resultBlock);
    }


    public void sendVideoMessage(Context context, long chatId, Map<String, Object> messageText, int countDown,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", messageText);
        funMap.put("@extra", rtId);
        addTask("sendVideoMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 发送语音消息，会触发以下3个事件
     * EUser_Td_Chat_New_Message,//新消息 data = MessageInfo
     * EUser_Td_Chat_Send_Message_Success,//发送成功 data = MessageInfo, dataEx = Long, old_message_id
     * EUser_Td_Chat_Send_Message_Fail,//发送失败 data = MessageInfo, dataEx = Long, old_message_id
     *
     * @param chatId         会话id
     * @param localAudioPath 本地语音路径
     * @param duration       语音时长，秒
     * @param resultBlock    回调
     */
    public void sendAudioMessage(Context context, long chatId, String localAudioPath, int duration, int countDown,TgResultBlock<TgResponse> resultBlock){
        Map<String, Object> audioDic = new HashMap<>();
        audioDic.put("@type", "inputFileLocal");
        audioDic.put("path", localAudioPath);
        sendAudioMessage(context,chatId,audioDic,duration,countDown,resultBlock);
    }
    public void sendAudioMessage(Context context, long chatId, Map<String, Object> audioDic, int duration, int countDown,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();

        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageAudio");
        messageText.put("audio", audioDic);
        messageText.put("duration", duration);
        Map<String, Object> messageContent = new HashMap<>();
        messageContent.put("@type", "inputMessageOss");
        messageContent.put("resource", messageText);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        funMap.put("chat_id", chatId);
        AppConfigInfo info = AppConfigInfo.getAppWithoutLoginConfigInfo();
        if (info != null&&!info.using_oss) {
            funMap.put("input_message_content", messageText);
        }else{
            funMap.put("input_message_content", messageContent);
        }

        funMap.put("@extra", rtId);
        addTask("sendAudioMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 发送文件消息，会触发以下3个事件
     * EUser_Td_Chat_New_Message,//新消息 data = MessageInfo
     * EUser_Td_Chat_Send_Message_Success,//发送成功 data = MessageInfo, dataEx = Long, old_message_id
     * EUser_Td_Chat_Send_Message_Fail,//发送失败 data = MessageInfo, dataEx = Long, old_message_id
     *
     * @param chatId        会话id
     * @param realFileName  UI显示的名称
     * @param localFilePath 本地文件路径
     * @param resultBlock   回调
     */
    public void sendFileMessage(Context context, long chatId, String realFileName, String localFilePath,int countDown, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> captionDic = new HashMap<>();
        captionDic.put("@type", "formattedText");
        captionDic.put("text", realFileName);
        captionDic.put("entities", new ArrayList<>());
        Map<String, Object> documentDic = new HashMap<>();
        documentDic.put("@type", "inputFileLocal");
        documentDic.put("path", localFilePath);
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageDocument");
        messageText.put("document", documentDic);
        messageText.put("caption", captionDic);

        Map<String, Object> messageContent = new HashMap<>();
        messageContent.put("@type", "inputMessageOss");
        messageContent.put("resource", messageText);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        funMap.put("chat_id", chatId);
        AppConfigInfo info = AppConfigInfo.getAppWithoutLoginConfigInfo();
        if (info != null&&!info.using_oss) {
            funMap.put("input_message_content", messageText);
        }else{
            funMap.put("input_message_content", messageContent);
        }
        funMap.put("@extra", rtId);
        addTask("sendFileMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 发送位置消息，会触发以下3个事件
     * EUser_Td_Chat_New_Message,//新消息 data = MessageInfo
     * EUser_Td_Chat_Send_Message_Success,//发送成功 data = MessageInfo, dataEx = Long, old_message_id
     * EUser_Td_Chat_Send_Message_Fail,//发送失败 data = MessageInfo, dataEx = Long, old_message_id
     *
     * @param chatId      会话id
     * @param latitude    经度
     * @param longitude   纬度
     * @param resultBlock 回调
     */
    public void sendLocationMessage(Context context, long chatId, double latitude, double longitude,int countDown, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> locationDic = new HashMap<>();
        locationDic.put("@type", "location");
        locationDic.put("latitude", latitude);
        locationDic.put("longitude", longitude);
        locationDic.put("horizontal_accuracy", 0);
        Map<String, Object> contentDic = new HashMap<>();
        contentDic.put("@type", "inputMessageLocation");
        contentDic.put("location", locationDic);
        contentDic.put("live_period", 0);
        contentDic.put("heading", 0);
        contentDic.put("proximity_alert_radius", 0);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        if(countDown>0){
            Map<String, Object> options = new HashMap<>();
            options.put("ttl_seconds",countDown);
            funMap.put("options", options);
        }
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", contentDic);
        funMap.put("@extra", rtId);
        addTask("sendLocationMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, transferErrorMsg(errorMsg(response))));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 发送截屏消息
     *
     * @param context
     * @param chatId      会话id
     * @param resultBlock 回调
     */
    public void sendScreenshotMessage(Context context, long chatId, TgResultBlock<TgResponse> resultBlock) {
        sendTextMessage(context, chatId, MessageInfo.getTextExMessage("{}", OtherEx_MessageType, OtherEx_MessageType_Screenshot), resultBlock);
    }

    /**
     * 发送加好友消息
     *
     * @param context
     * @param chatId      会话id
     * @param resultBlock 回调
     */
    public void sendBeFriendMessage(Context context, long chatId, TgResultBlock<TgResponse> resultBlock) {
        sendTextMessage(context, chatId, MessageInfo.getTextExMessage("{}", OtherEx_MessageType, OtherEx_MessageType_BeFriend), resultBlock);
    }


    /**
     * 发送本地文本消息,目前仅音视频通话需要，会触发以下3个事件
     * EUser_Td_Chat_New_Message,//新消息 data = MessageInfo
     * EUser_Td_Chat_Send_Message_Success,//发送成功 data = MessageInfo, dataEx = Long, old_message_id
     * EUser_Td_Chat_Send_Message_Fail,//发送失败 data = MessageInfo, dataEx = Long, old_message_id
     *
     * @param chatId       会话id
     * @param senderUserId 发送者id
     * @param text         文本内容
     * @param resultBlock  回调
     */
    public void sendLocalCustomMessage(Context context, long chatId, long senderUserId, String text, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> textDic = new HashMap<>();
        textDic.put("@type", "formattedText");
        textDic.put("text", text);
        textDic.put("entities", new ArrayList<>());
        Map<String, Object> messageText = new HashMap<>();
        messageText.put("@type", "inputMessageText");
        messageText.put("text", textDic);
        messageText.put("disable_web_page_preview", false);
        messageText.put("clear_draft", false);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "addLocalMessage");
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", messageText);
        funMap.put("disable_notification", true);
//        funMap.put("sender_user_id", senderUserId);
        Map<String, Object> senderMap = new HashMap<>();
        senderMap.put("@type", "messageSenderUser");
        senderMap.put("user_id", senderUserId);
        funMap.put("sender", senderMap);
        funMap.put("@extra", rtId);
        addTask("sendLocalCustomMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void forwardMessage(long chatId, MessageInfo forwardMsg) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> contentMap = new HashMap<>();
        contentMap.put("@type", "inputMessageForwarded");
        contentMap.put("from_chat_id", forwardMsg.chat_id);
        contentMap.put("message_id", forwardMsg.id);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendMessage");
        funMap.put("chat_id", chatId);
        funMap.put("input_message_content", contentMap);
        funMap.put("@extra", rtId);
        addTask("forwardMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
            }
        });
    }


    public void closeSecretChat(Context context,long secret_chat_id,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "closeSecretChat");
        funMap.put("secret_chat_id", secret_chat_id);
        funMap.put("@extra", rtId);
        addTask("forwardMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getSecretChat(Context context, long secret_chat_id, TgResultBlock<SecretChatInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getSecretChat");
        funMap.put("secret_chat_id", secret_chat_id);
        funMap.put("@extra", rtId);
        addTask("forwardMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                SecretChatInfo chatInfo = new Gson().fromJson(response,SecretChatInfo.class);
                resultBlock.onResult(request, response, chatInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 转发消息
     *
     * @param chatId 转发到-会话id
     * @param msgs   转发的消息列表
     */
    public void forwardMessages(Context context, long chatId, List<MessageInfo> msgs) {
        for (MessageInfo msg : msgs) {
            if (msg.sendState() == MessageSendState.MessageSendState_Success) {
                boolean isNormalForward = false;
                if (msg.messageType == MessageType.MessageType_Photo) {
                    //图片
                    isNormalForward = true;
                }
                if (msg.messageType == MessageType.MessageType_Video) {
                    //视频
                    isNormalForward = true;
                }
                if (msg.messageType == MessageType.MessageType_Audio) {
                    //语音
                    isNormalForward = true;
                }
                if (msg.messageType == MessageType.MessageType_Voice_Note) {
                    //语音
                    isNormalForward = true;
                }
                if (msg.messageType == MessageType.MessageType_Document) {
                    //文件
                    isNormalForward = true;
                }
                if (msg.messageType == MessageType.MessageType_Location) {
                    //位置
                    isNormalForward = true;
                }
                if (msg.messageType == MessageType.MessageType_Animation) {
                    //位置
                    isNormalForward = true;
                }
                if (msg.messageType == MessageType.MessageType_Contact) {
                    //位置
                    isNormalForward = true;
                }
                if (msg.messageType == MessageType.MessageType_Text&&msg.reply_markup!=null&&!Common.isEmpty(msg.reply_markup.getTemp())) {
                    //位置
                    isNormalForward = true;
                }
                if (isNormalForward) {
                    forwardMessage(chatId, msg);
                    continue;
                }
            }
            //其他消息类型作为文本消息发送
            sendTextMessage(context, chatId, msg.toString(), new TgResultBlock<TgResponse>() {
                @Override
                public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {
                }

                @Override
                public void onTimeout(Map<String, Object> request) {
                }
            });
        }
    }

    /**
     * 设置一批消息已读
     *
     * @param chatId 会话id
     * @param ids    消息id列表
     */
    public void setMessagesReaded(long chatId, List<Long> ids) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "viewMessages");
        funMap.put("chat_id", chatId);
        funMap.put("message_ids", ids);
        funMap.put("force_read", true);
        funMap.put("@extra", rtId);
        addTask("setMessagesReaded", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
            }
        });
    }

    /**
     * 删除或者撤销单聊消息，执行后会收到以下事件，判断DeleteMessagesInfo.isRealDelete()为true时，把消息列表中相关消息删除
     * EUser_Td_Chat_Delete_Message,//删除消息 data = DeleteMessagesInfo
     *
     * @param chatId      会话id
     * @param ids         消息ids
     * @param isRevoke    是否撤回
     * @param resultBlock 回调
     */
    public void deleteP2pMessages(Context context, long chatId, List<Long> ids, boolean isRevoke, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "deleteMessages");
        funMap.put("chat_id", chatId);
        funMap.put("message_ids", ids);
        funMap.put("revoke", isRevoke);
        funMap.put("@extra", rtId);
        addTask("deleteP2pMessages", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 删除或者撤销超级群组消息，执行后会收到以下事件，判断DeleteMessagesInfo.isRealDelete()为true时，把消息列表中相关消息删除
     * EUser_Td_Chat_Delete_Message,//删除消息 data = DeleteMessagesInfo
     *
     * @param chatId      会话id
     * @param ids         消息ids
     * @param isRevoke    是否撤回
     * @param resultBlock 回调
     */
    public void deleteSuperGroupMessages(Context context, long chatId, List<Long> ids, boolean isRevoke, TgResultBlock<TgResponse> resultBlock) {
        if (isRevoke) {
            deleteP2pMessages(context, chatId, ids, isRevoke, resultBlock);
        } else {
            deleteSuperGroupMessages(context, chatId, ids, resultBlock);
        }
    }

    public void deleteSuperGroupMessages(Context context, long chatId, List<Long> ids, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        List<Long> toIds = new ArrayList<>();
        for (long id : ids) {
            Long new_id = id >> 20;
            toIds.add(new_id);
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("channelId", ChatInfo.toServerPeerId(chatId));
        parameters.put("messageIds", toIds);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "channel.cleanMessages");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("deleteSuperGroupMessages", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (customResultCode(response) != 200) {
                    resultBlock.onResult(request, response, new TgResponse(false, "删除失败"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getMessage(Context context, long chatId, long message_id, TgResultBlock<MessageInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();

        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getMessage");
        funMap.put("chat_id", chatId);
        funMap.put("message_id", message_id);
        funMap.put("@extra", rtId);
        addTask("getMessage", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                MessageInfo info = null;
                if (response != null) {
                    info = new Gson().fromJson(response, MessageInfo.class);
                }
                if(info!=null){
                    parseMessageContent(response.getAsJsonObject("content"), info);
                }
                if (customResultCode(response) != 200) {
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response,null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="群组相关">

    /**
     * 获取超级群组资料
     *
     * @param group_id    超级群组id
     * @param resultBlock 回调
     */
    public void getSuperGroupInfo(Context context, long group_id, TgResultBlock<SuperGroupInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getSupergroup");
        funMap.put("supergroup_id", group_id);
        funMap.put("@extra", rtId);
        addTask("getSuperGroupInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    if(resultBlock!=null){
                        resultBlock.onResult(request, response, null);
                    }

                } else {
                    SuperGroupInfo info = new Gson().fromJson(response, SuperGroupInfo.class);
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Chat_Super_Group_info, info,group_id));
                    if(resultBlock!=null) {
                        resultBlock.onResult(request, response, info);
                    }
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                if(resultBlock!=null) {
                    resultBlock.onTimeout(request);
                }
            }
        });
    }

    public void updateChatInfoChatPermession(Context context,ChatInfo chatInfo){
        updateChatInfoChatPermession(context,chatInfo,true,null);
    }

    public void updateChatInfoChatPermession(Context context,ChatInfo chatInfo,TgResultBlock<GroupManagePermissionInfo> resultBlock){
        updateChatInfoChatPermession(context,chatInfo,true,resultBlock);
    }

    public void updateChatInfoChatPermession(Context context,ChatInfo chatInfo,boolean isParral,TgResultBlock<GroupManagePermissionInfo> resultBlock){
        if(chatInfo==null){
            if(resultBlock!=null){
                resultBlock.onResult(null,null,null);
            }
            return;
        }
        if(!chatInfo.isGroup()){
            if(resultBlock!=null){
                resultBlock.onResult(null,null,null);
            }
            return;
        }
        if(chatInfo.permissions==null){
            ChatPermissions curPermissions = new ChatPermissions();
            curPermissions.can_send_messages = true;
            curPermissions.can_send_media_messages = true;
            curPermissions.can_send_polls = true;
            curPermissions.can_send_other_messages = true;
            curPermissions.can_add_web_page_previews = true;
            curPermissions.can_change_info = true;
            curPermissions.can_invite_users = true;
            curPermissions.can_pin_messages = true;
            chatInfo.permissions = curPermissions;
        }
        if(isParral){
            refreshGroupBannedRightEx(context,chatInfo,resultBlock);
            refreshFilterKeywords(context,chatInfo,resultBlock);
        }else{
            refreshGroupBannedRightEx(context, chatInfo, new TgResultBlock<GroupManagePermissionInfo>() {
                @Override
                public void onResult(Map<String, Object> request, JsonObject response, GroupManagePermissionInfo obj) {
                    refreshFilterKeywords(context,chatInfo,resultBlock);
                }

                @Override
                public void onTimeout(Map<String, Object> request) {

                }
            });
        }

    }

    private void refreshGroupBannedRightEx(Context context,ChatInfo chatInfo,TgResultBlock<GroupManagePermissionInfo> resultBlock){
        getGroupBannedRightEx(context, chatInfo.id, new TgResultBlock<GroupManagePermissionInfo>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, GroupManagePermissionInfo obj) {
                if(obj!=null&&chatInfo.permissions!=null){
                    chatInfo.permissions.banWhisper = obj.banWhisper;
                    chatInfo.permissions.banSendKeyword = obj.banSendKeyword;
                    chatInfo.permissions.banSendQRcode = obj.banSendQRcode;
                    chatInfo.permissions.banSendWebLink = obj.banSendWebLink;
                    chatInfo.permissions.kickWhoSendKeyword = obj.kickWhoSendKeyword;
                    chatInfo.permissions.showKickMessage = obj.showKickMessage;
                }
                if(resultBlock!=null){
                    resultBlock.onResult(request,response,obj);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if(resultBlock!=null){
                    resultBlock.onResult(null,null,null);
                }
            }
        });
    }

    private void refreshFilterKeywords(Context context,ChatInfo chatInfo,TgResultBlock<GroupManagePermissionInfo> resultBlock){
        getFilterKeywords(context, chatInfo.id, new TgResultBlock<List<String>>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, List<String> obj) {
                if(obj!=null&&chatInfo.permissions!=null){
                    chatInfo.permissions.keywords = obj;
                }

                if(resultBlock!=null){
                    resultBlock.onResult(request,response,null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if(resultBlock!=null){
                    resultBlock.onResult(null,null,null);
                }
            }
        });
    }

    public void getGroupBannedRightEx(Context context, long chatId,TgResultBlock<GroupManagePermissionInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "chats.getBannedRightex");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("getBannedRightex", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                if (data != null) {
                    GroupManagePermissionInfo info = new Gson().fromJson(data, GroupManagePermissionInfo.class);
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getGroupOnlineCount(Context context, long chatId,TgResultBlock<ChatOnlineMemberCountInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "channel.countOnline");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("channelID", ChatInfo.toServerPeerId(chatId));
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("getBannedRightex", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                if (data != null) {
                    ChatOnlineMemberCountInfo info = new Gson().fromJson(data, ChatOnlineMemberCountInfo.class);
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void modifyGroupBannedRightEx(Context context, long chatId,boolean banWhisper,boolean banSendWebLink
            ,boolean banSendQRcode,boolean banSendKeyword,boolean kickWhoSendKeyword
            ,boolean ShowKickMessage,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        parameters.put("banWhisper",banWhisper);
        parameters.put("banSendWebLink",banSendWebLink);
        parameters.put("banSendQRcode",banSendQRcode);
        parameters.put("banSendKeyword",banSendKeyword);
        parameters.put("kickWhoSendKeyword",kickWhoSendKeyword);
        parameters.put("showKickMessage",ShowKickMessage);
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "chats.modifyBannedRightex");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("modifyBannedRightex", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getFilterKeywords(Context context, long chatId,TgResultBlock<List<String>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "chats.getFilterKeywords");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("getFilterKeywords", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonArray data = customResultListData(response,true);
                if (data != null) {
                    List<String> info = new Gson().fromJson(data, new TypeToken<List<String>>() {}.getType());
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void setFilterKeywords(Context context, long chatId, List<String> keywords,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        parameters.put("keywords",keywords);

        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "chats.setFilterKeywords");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("setFilterKeywords", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void toggleChannelPublic(Context context, long supergroup_id, boolean is_public,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "toggleChannelPublic");
        funMap.put("supergroup_id", supergroup_id);
        funMap.put("is_public", is_public);
        funMap.put("@extra", rtId);
        addTask("toggleChannelPublic", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取超级群组扩展资料
     *
     * @param group_id    超级群组id
     * @param resultBlock 回调
     */
    public void getSuperGroupFullInfo(Context context, long group_id, TgResultBlock<SuperGroupFullInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getSupergroupFullInfo");
        funMap.put("supergroup_id", group_id);
        funMap.put("@extra", rtId);
        addTask("getSuperGroupFullInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    SuperGroupFullInfo info = new Gson().fromJson(response, SuperGroupFullInfo.class);
                    resultBlock.onResult(request, response, info);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 根据条件获取超级群组成员
     * 为逻辑简单，目前不做分页，offset传0，limit传200
     *
     * @param group_id    超级群组id
     * @param type        "supergroupMembersFilterRecent":成员列表，"supergroupMembersFilterAdministrators":管理员列表，"supergroupMembersFilterRestricted":禁言列表
     * @param keyword     搜索关键字
     * @param offset      偏移 - 0
     * @param limit       最大个数 - 200
     * @param resultBlock 回调
     */
    public void getSuperGroupMembers(Context context,long chatId, long group_id, String type, String keyword, int offset, int limit, TgResultBlock<List<GroupMemberInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getSupergroupMembers");
        funMap.put("supergroup_id", group_id);
        if(!TextUtils.isEmpty(type)){
            Map<String, Object> filter = new HashMap<>();
            filter.put("@type", type);
            if (!StringUtils.isEmpty(keyword)) {
                filter.put("query", keyword);
            }
            funMap.put("filter", filter);
        }

        funMap.put("offset", offset);
        funMap.put("limit", limit);
        funMap.put("@extra", rtId);
        addTask("getSuperGroupMembers", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<GroupMemberInfo> members = new ArrayList<>();
                if (response != null && response.has("members")) {
                    if (!isResultError(response)) {
                        JsonArray list = response.getAsJsonArray("members");
                        if (list != null) {
                            members = new Gson().fromJson(list, new TypeToken<List<GroupMemberInfo>>() {
                            }.getType());
                        }
                    }
                }
                if(!Common.isEmpty(members)){
                    List<Long> sameList = new ArrayList<>();
                    List<UserInfo> userInfos = TelegramManager.getTelegramManager().getTgData().getMyContacts();
                    for(GroupMemberInfo memberInfo:members){
                        TelegramManager.getTelegramManager().getTgData().putGroupNickNames(chatId,memberInfo.user_id,memberInfo.nickname);
                        for(UserInfo item:userInfos){
                            if(item.id == memberInfo.user_id){
                                sameList.add(item.id);
                            }
                        };
                    }

                    TelegramManager.getTelegramManager().requestOrgContactInfos(context, sameList, new TgResultBlock<List<OrgUserInfo>>() {
                        @Override
                        public void onResult(Map<String, Object> request, JsonObject response, List<OrgUserInfo> obj) {
                            if (obj != null) {
                                for (OrgUserInfo orgUserInfo : obj) {
                                    TelegramManager.getTelegramManager().getTgData().putUserRealyNames(orgUserInfo.uId,orgUserInfo.displayName());
                                }
                            }
                        }

                        @Override
                        public void onTimeout(Map<String, Object> request) {

                        }
                    });
                }
                resultBlock.onResult(request, response, members);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    /**
     * 获得某个成员信息
     *
     * @param chatId       会话id
     * @param memberUserId 成员id
     * @param resultBlock  回调
     */
    public void getGroupMember(Context context, long chatId, long memberUserId, TgResultBlock<GroupMemberInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getChatMember");
        funMap.put("chat_id", chatId);
        funMap.put("user_id", memberUserId);
        funMap.put("@extra", rtId);
        addTask("getChatMember", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    if(resultBlock!=null){
                        resultBlock.onResult(request, response, null);
                    }

                } else {
                    GroupMemberInfo member = new Gson().fromJson(response, GroupMemberInfo.class);
                    TelegramManager.getTelegramManager().getTgData().putGroupNickNames(chatId,memberUserId,member.nickname);
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_User_Nick_Name_GET,chatId));
                    if(resultBlock!=null) {
                        resultBlock.onResult(request, response, member);
                    }
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                if(resultBlock!=null) {
                    resultBlock.onTimeout(request);
                }
            }
        });
    }

    /**
     * 超级群组增加成员
     *
     * @param chatId      会话id
     * @param memberIds   新增成员ids合集
     * @param resultBlock 回调
     */
    public void addMembers2SuperGroup(Context context, long chatId, List<Long> memberIds, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "addChatMembers");
        funMap.put("chat_id", chatId);
        funMap.put("user_ids", memberIds);
        funMap.put("@extra", rtId);
        addTask("addMembers2SuperGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 设置群组名称
     *
     * @param chatId      会话id
     * @param groupName   群组名称
     * @param resultBlock 回调
     */
    public void setGroupName(Context context, long chatId, String groupName, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatTitle");
        funMap.put("chat_id", chatId);
        funMap.put("title", groupName);
        funMap.put("@extra", rtId);
        addTask("setGroupName", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 设置群组头像
     *
     * @param chatId      会话id
     * @param localPath   图片本地地址
     * @param resultBlock 回调
     */
    public void setGroupPhoto(Context context, long chatId, String localPath, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> photo = new HashMap<>();
        photo.put("@type", "inputFileLocal");
        photo.put("path", localPath);
        Map<String, Object> inputChatPhotoStatic = new HashMap<>();
        inputChatPhotoStatic.put("@type", "inputChatPhotoStatic");
        inputChatPhotoStatic.put("photo", photo);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatPhoto");
        funMap.put("chat_id", chatId);
        funMap.put("photo", inputChatPhotoStatic);
        funMap.put("@extra", rtId);
        addTask("setGroupPhoto", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 移除成员
     *
     * @param chatId      会话id
     * @param toDelUserId 被移除userid
     * @param resultBlock 回调
     */
    public void removeMemberFromGroup(Context context, long chatId, long toDelUserId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> status = new HashMap<>();
        status.put("@type", "chatMemberStatusLeft");
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatMemberStatus");
        funMap.put("chat_id", chatId);
        funMap.put("user_id", toDelUserId);
        funMap.put("status", status);
        funMap.put("@extra", rtId);
        addTask("removeMemberFromGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 提升现有群组成员为管理员
     *
     * @param chatId      会话id
     * @param toAddUserId 提升成员userid
     * @param resultBlock 回调
     */
    public void addManager2Group(Context context, long chatId, long toAddUserId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> status = new HashMap<>();
        status.put("@type", "chatMemberStatusAdministrator");
        status.put("can_be_edited", true);
        status.put("can_change_info", true);
        status.put("can_post_messages", true);
        status.put("can_edit_messages", true);
        status.put("can_delete_messages", true);
        status.put("can_invite_users", true);
        status.put("can_restrict_members", true);
        status.put("can_pin_messages", true);
        status.put("can_promote_members", true);
        status.put("is_anonymous", true);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatMemberStatus");
        funMap.put("chat_id", chatId);
        funMap.put("user_id", toAddUserId);
        funMap.put("status", status);
        funMap.put("@extra", rtId);
        addTask("addManager2Group", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 管理员降级为普通成员
     * 先禁言再调用此方法，才会有效-超级群组移除管理员
     *
     * @param chatId      会话id
     * @param toDelUserId 被降级的userid
     * @param resultBlock 回调
     */
    public void removeManagerFromGroup(Context context, long chatId, long toDelUserId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> status = new HashMap<>();
        status.put("@type", "chatMemberStatusMember");
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatMemberStatus");
        funMap.put("chat_id", chatId);
        funMap.put("user_id", toDelUserId);
        funMap.put("status", status);
        funMap.put("@extra", rtId);
        addTask("removeManagerFromGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 退出群组
     *
     * @param chatId      会话id
     * @param resultBlock 回调
     */
    public void leaveGroup(Context context, long chatId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "leaveChat");
        funMap.put("chat_id", chatId);
        funMap.put("@extra", rtId);
        addTask("leaveGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 解散群组
     *
     * @param groupId     群组id
     * @param resultBlock 回调
     */
    public void deleteGroup(Context context, long groupId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "deleteSupergroup");
        funMap.put("supergroup_id", groupId);
        funMap.put("@extra", rtId);
        addTask("deleteGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 禁言或者取消禁言某成员
     *
     * @param chatId      会话id
     * @param userId      成员id
     * @param isBan       禁言或者取消禁言
     * @param resultBlock 回调
     */
    public void banMemberFromSuperGroup(Context context, long chatId, long userId, boolean isBan, TgResultBlock<TgResponse> resultBlock) {
        if (isBan) {
            banMemberFromSuperGroup(context, chatId, userId, resultBlock);
        } else {
            unbanMemberFromSuperGroup(context, chatId, userId, resultBlock);
        }
    }

    public void banMemberFromSuperGroup(Context context, long chatId, long toBanUserId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> permissions = new HashMap<>();
        permissions.put("@type", "chatPermissions");
        permissions.put("can_send_messages", false);
        permissions.put("can_send_media_messages", false);
        permissions.put("can_send_polls", false);
        permissions.put("can_send_other_messages", false);
        permissions.put("can_add_web_page_previews", false);
        permissions.put("can_change_info", false);
        permissions.put("can_invite_users", false);
        permissions.put("can_pin_messages", false);
        Map<String, Object> status = new HashMap<>();
        status.put("@type", "chatMemberStatusRestricted");
        status.put("is_member", true);
        status.put("restricted_until_date", 0);
        status.put("permissions", permissions);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatMemberStatus");
        funMap.put("chat_id", chatId);
        funMap.put("user_id", toBanUserId);
        funMap.put("status", status);
        funMap.put("@extra", rtId);
        addTask("banMemberFromSuperGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    private void unbanMemberFromSuperGroup(Context context, long chatId, long toUnbanUserId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> status = new HashMap<>();
        status.put("@type", "chatMemberStatusMember");
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatMemberStatus");
        funMap.put("chat_id", chatId);
        funMap.put("user_id", toUnbanUserId);
        funMap.put("status", status);
        funMap.put("@extra", rtId);
        addTask("unbanMemberFromSuperGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 全体禁言或者取消全体禁言
     *
     * @param chatId      会话id
     * @param isBanAll    全体禁言或者取消全体禁言
     * @param resultBlock 回调
     */
    public void banAllToGroup(Context context, long chatId, boolean isBanAll,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        ChatPermissions curPermissions = null;
        ChatInfo chat = getTgData().chatInfo(chatId);
        curPermissions = chat.permissions;
        if (curPermissions == null) {
            curPermissions = new ChatPermissions();
            curPermissions.can_send_messages = true;
            curPermissions.can_send_media_messages = true;
            curPermissions.can_send_polls = true;
            curPermissions.can_send_other_messages = true;
            curPermissions.can_add_web_page_previews = true;
            curPermissions.can_change_info = true;
            curPermissions.can_invite_users = true;
            curPermissions.can_pin_messages = true;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> permissions = new HashMap<>();
        permissions.put("@type", "chatPermissions");
        permissions.put("can_send_messages",!isBanAll);
        permissions.put("can_send_media_messages", !isBanAll);
        permissions.put("can_send_polls", !isBanAll);
        permissions.put("can_send_other_messages", !isBanAll);
        permissions.put("can_add_web_page_previews", !isBanAll);
        permissions.put("can_change_info", curPermissions.can_change_info);
        permissions.put("can_invite_users", curPermissions.can_invite_users);
        permissions.put("can_pin_messages", curPermissions.can_pin_messages);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatPermissions");
        funMap.put("chat_id", chatId);
        funMap.put("permissions", permissions);
        funMap.put("@extra", rtId);
        addTask("banAllToGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void banMediaToGroup(Context context, ChatInfo chatInfo,final boolean isBanMedia,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        if(chatInfo==null||chatInfo.permissions==null){
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> permissions = new HashMap<>();
        permissions.put("@type", "chatPermissions");
        permissions.put("can_send_messages",chatInfo.permissions.can_send_messages);
        permissions.put("can_send_media_messages", !isBanMedia);
        permissions.put("can_send_polls", chatInfo.permissions.can_send_polls);
        permissions.put("can_send_other_messages", chatInfo.permissions.can_send_other_messages);
        permissions.put("can_add_web_page_previews", chatInfo.permissions.can_add_web_page_previews);
        permissions.put("can_change_info", chatInfo.permissions.can_change_info);
        permissions.put("can_invite_users", chatInfo.permissions.can_invite_users);
        permissions.put("can_pin_messages", chatInfo.permissions.can_pin_messages);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatPermissions");
        funMap.put("chat_id", chatInfo.id);
        funMap.put("permissions", permissions);
        funMap.put("@extra", rtId);
        addTask("banAllToGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    chatInfo.permissions.can_send_media_messages = !isBanMedia;
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 全体禁止私聊或者取消
     *
     * @param chatId      会话id
     * @param isBlock     全体禁止私聊或者取消
     * @param resultBlock 回调
     */
    public void blockPrivateChatToGroup(Context context, long chatId, boolean isBlock, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        ChatPermissions curPermissions = null;
        ChatInfo chat = getTgData().chatInfo(chatId);
        curPermissions = chat.permissions;
        if (curPermissions == null) {
            curPermissions = new ChatPermissions();
            curPermissions.can_send_messages = true;
            curPermissions.can_send_media_messages = true;
            curPermissions.can_send_polls = true;
            curPermissions.can_send_other_messages = true;
            curPermissions.can_add_web_page_previews = true;
            curPermissions.can_change_info = true;
            curPermissions.can_invite_users = true;
            curPermissions.can_pin_messages = true;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> permissions = new HashMap<>();
        permissions.put("@type", "chatPermissions");
        permissions.put("can_send_media_messages", curPermissions.can_send_media_messages);
        permissions.put("can_send_polls", curPermissions.can_send_polls);
        permissions.put("can_send_other_messages", curPermissions.can_send_other_messages);
        permissions.put("can_add_web_page_previews", !isBlock);
        permissions.put("can_change_info", curPermissions.can_change_info);
        permissions.put("can_invite_users", curPermissions.can_invite_users);
        permissions.put("can_pin_messages", curPermissions.can_pin_messages);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatPermissions");
        funMap.put("chat_id", chatId);
        funMap.put("permissions", permissions);
        funMap.put("@extra", rtId);
        addTask("blockPrivateChatToGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 设置是否可以加群员
     *
     * @param chatId      会话id
     * @param isCan       可以或者不可以
     * @param resultBlock 回调
     */
    public void canInvideMemberToGroup(Context context, long chatId, boolean isCan, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        ChatPermissions curPermissions = null;
        ChatInfo chat = getTgData().chatInfo(chatId);
        curPermissions = chat.permissions;
        if (curPermissions == null) {
            curPermissions = new ChatPermissions();
            curPermissions.can_send_messages = true;
            curPermissions.can_send_media_messages = true;
            curPermissions.can_send_polls = true;
            curPermissions.can_send_other_messages = true;
            curPermissions.can_add_web_page_previews = true;
            curPermissions.can_change_info = true;
            curPermissions.can_invite_users = true;
            curPermissions.can_pin_messages = true;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> permissions = new HashMap<>();
        permissions.put("@type", "chatPermissions");
        permissions.put("can_send_media_messages", curPermissions.can_send_media_messages);
        permissions.put("can_send_polls", curPermissions.can_send_polls);
        permissions.put("can_send_other_messages", curPermissions.can_send_other_messages);
        permissions.put("can_add_web_page_previews", curPermissions.can_add_web_page_previews);
        permissions.put("can_change_info", curPermissions.can_change_info);
        permissions.put("can_invite_users", isCan);
        permissions.put("can_pin_messages", curPermissions.can_pin_messages);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setChatPermissions");
        funMap.put("chat_id", chatId);
        funMap.put("permissions", permissions);
        funMap.put("@extra", rtId);
        addTask("canInvideMemberToGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 删除某人全部消息
     *
     * @param chatId      会话id
     * @param userId      成员id
     * @param resultBlock 回调
     */
    public void delAllHisMessagesFromSuperGroup(Context context, long chatId, long userId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "deleteChatMessagesFromUser");
        funMap.put("chat_id", chatId);
        funMap.put("user_id", userId);
        funMap.put("@extra", rtId);
        addTask("delAllHisMessagesFromSuperGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="联系人相关">

    /**
     * 同步联系人
     */
    public void syncMyContacts() {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getContacts");
        funMap.put("@extra", rtId);
        addTask("syncMyContacts", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (response != null && response.has("@type")) {
                    if (!isResultError(response)) {
                        String type = response.get("@type").getAsString();
                        if ("users".equals(type) && response.has("user_ids")) {
                            JsonArray contactIds = response.getAsJsonArray("user_ids");
                            if (contactIds != null && contactIds.size() > 0) {
                                for (int i = 0; i < contactIds.size(); i++) {
                                    long userId = contactIds.get(i).getAsLong();
                                    getUserSimpleInfo(userId);
                                }
                            }
                        }
                    }
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                Constants.Logd(TAG, "invoke syncMyContacts timeout");
            }
        });
    }


    public void importContacts(Context context, List<MobileContactInfo> contactInfos, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "importContacts");
        funMap.put("contacts",contactInfos);
        funMap.put("@extra", rtId);
        addTask("importContacts", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    if(response.has("user_ids")){
                        JsonArray contactIds = response.getAsJsonArray("user_ids");
                        if (contactIds != null && contactIds.size() > 0) {
                            for (int i = 0; i < contactIds.size(); i++) {
                                long userId = contactIds.get(i).getAsLong();
                                if(contactInfos!=null&&contactInfos.size()>i){
                                    contactInfos.get(i).user_id = userId;
                                }
                            }
                        }
                    }

                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void changeImportedContacts(List<MobileContactInfo> contactInfos, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "changeImportedContacts");
        funMap.put("contacts",contactInfos);
        funMap.put("@extra", rtId);
        addTask("changeImportedContacts", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    if(response.has("user_ids")){
                        JsonArray contactIds = response.getAsJsonArray("user_ids");
                        if (contactIds != null && contactIds.size() > 0) {
                            for (int i = 0; i < contactIds.size(); i++) {
                                long userId = contactIds.get(i).getAsLong();
                                if(contactInfos!=null&&contactInfos.size()>i){
                                    contactInfos.get(i).user_id = userId;
                                }
                            }
                        }
                    }
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getUserSimpleInfo(long userId) {
        getUserSimpleInfo(userId,null);
    }

    public void getUserSimpleInfo(long userId,TgResultBlock<UserInfo> block) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getUser");
        funMap.put("user_id", userId);
        funMap.put("@extra", rtId);
        addTask("getUserSimpleInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                UserInfo userInfo = null;
                if (response != null && response.has("@type")) {
                    if (!isResultError(response)) {
                        String type = response.get("@type").getAsString();
                        if ("user".equals(type)) {
                            userInfo = parseUserInfo(response);
                        }
                    }
                }
                if(block!=null){
                    block.onResult(request,response,userInfo);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {

            }
        });
    }

    /**
     * 加入或取消黑名单
     *
     * @param userId      用户id
     * @param isBlock     加入or取消
     * @param resultBlock 回调
     */
    public void blockUser(Context context, long userId, boolean isBlock, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> userMap = new HashMap<>();
        userMap.put("@type", "messageSenderUser");
        userMap.put("user_id",userId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "toggleMessageSenderIsBlocked");
        funMap.put("is_blocked",isBlock);
        funMap.put("sender", userMap);
        funMap.put("@extra", rtId);
        addTask("blockUser", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 增加好友
     *
     * @param user        用户信息
     * @param resultBlock 回调
     */
    public void addContact(Context context, UserInfo user, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> contact = new HashMap<>();
        contact.put("@type", "contact");
        contact.put("first_name", user.first_name == null ? "" : user.first_name);
        contact.put("last_name", user.last_name == null ? "" : user.last_name);
        contact.put("user_id", user.id);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "addContact");
        funMap.put("contact", contact);
        funMap.put("share_phone_number", false);
        funMap.put("@extra", rtId);
        addTask("addContact", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 设置联系人备注
     *
     * @param userId      用户id
     * @param nickName    备注
     * @param resultBlock 回调
     */
    public void setContactNickName(Context context, long userId, String nickName, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> contact = new HashMap<>();
        contact.put("@type", "contact");
        contact.put("first_name", nickName);
        contact.put("last_name", "");
        contact.put("user_id", userId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "addContact");
        funMap.put("contact", contact);
        funMap.put("share_phone_number", false);
        funMap.put("@extra", rtId);
        addTask("setContactNickName", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 删除好友
     *
     * @param userId      用户id
     * @param resultBlock 回调
     */
    public void deleteContact(Context context, long userId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "removeContacts");
        List<Long> ids = new ArrayList<>();
        ids.add(userId);
        funMap.put("user_ids", ids);
        funMap.put("@extra", rtId);
        addTask("deleteContact", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Remove_Contact,userId));
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 设置当前用户username，允许为空，为空表示删除
     *
     * @param userName    用户名
     * @param resultBlock 回调
     */
    public void setMyUserName(Context context, String userName, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setUsername");
        funMap.put("username", userName);
        funMap.put("@extra", rtId);
        addTask("setMyUserName", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorCode(response), errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 设置当前用户昵称
     *
     * @param nickName    昵称
     * @param resultBlock 回调
     */
    public void setMyNickName(Context context, String nickName, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setName");
        funMap.put("first_name", nickName);
        funMap.put("last_name", "");
        funMap.put("@extra", rtId);
        addTask("setMyNickName", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 设置我的头像
     *
     * @param localPath   本地路径
     * @param resultBlock 回调
     */
    public void setMyPhoto(Context context, String localPath, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> photo = new HashMap<>();
        photo.put("@type", "inputFileLocal");
        photo.put("path", localPath);
        Map<String, Object> inputChatPhotoStatic = new HashMap<>();
        inputChatPhotoStatic.put("@type", "inputChatPhotoStatic");
        inputChatPhotoStatic.put("photo", photo);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setProfilePhoto");
        funMap.put("photo", inputChatPhotoStatic);
        funMap.put("@extra", rtId);
        addTask("setMyPhoto", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void disableInviteLink(Context context, long chatId,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "chats.disableInviteLink");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("disableInviteLink", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void confirmQrCodeAuthentication(Context context, String link, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "confirmQrCodeAuthentication");
        funMap.put("link", link);
        funMap.put("@extra", rtId);
        addTask("confirmQrCodeAuthentication", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    String errorMsg = errorMsg(response);
                    if("400_AUTH_TOKEN_EXPIRED".equals(errorMsg)){
                        errorMsg = "二维码已过期";
                    }else if("400_AUTH_TOKEN_INVALID".equals(errorMsg)){
                        errorMsg = "二维码已失效";
                    }
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void setBio(Context context, String bio, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setBio");
        funMap.put("bio", bio);
        funMap.put("@extra", rtId);
        addTask("setBio", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    String errorMsg = errorMsg(response);
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 生成群链接邀请
     */
    public void generateChatInviteLink(Context context, long chatId, TgResultBlock<ChatInviteLink> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "generateChatInviteLink");
        funMap.put("chat_id", chatId);
        funMap.put("@extra", rtId);
        addTask("generateChatInviteLink", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    ChatInviteLink inviteLink = new Gson().fromJson(response, ChatInviteLink.class);
                    resultBlock.onResult(request, response, inviteLink);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    /**
     * 验证群链接邀请
     */
    public void checkChatInviteLink(Context context, String invite_link,boolean isTransferLink, TgResultBlock<RequestData<ChatInviteLink>> resultBlock) {
        if(TextUtils.isEmpty(invite_link)){
            return;
        }
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "checkChatInviteLink");
        funMap.put("invite_link", isTransferLink?tansferInviteLink(invite_link):invite_link);
        funMap.put("@extra", rtId);
        addTask("checkChatInviteLink", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    ChatInviteLink inviteLink = null;
                    try {
                        inviteLink = new Gson().fromJson(response, ChatInviteLink.class);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    if(inviteLink!=null&&inviteLink.chat_id!=0){
                        final ChatInviteLink finalInviteLink = inviteLink;
                        TelegramManager.getTelegramManager().getGroupMember(context, inviteLink.chat_id, UserInfo.getUserInfo().id, new TgResultBlock<GroupMemberInfo>() {
                            @Override
                            public void onResult(Map<String, Object> request1, JsonObject response1, GroupMemberInfo obj) {
                                if(obj!=null){
//                                    resultBlock.onResult(request, response, new RequestData<ChatInviteLink>("已是群成员"));
                                    List<ChatInfo> chatInfos = TelegramManager.getTelegramManager().getTgData().getChatList();
                                    ChatInfo targetChatInfo = null;
                                    if(chatInfos!=null&&chatInfos.size()>0){
                                        for(ChatInfo chatInfo:chatInfos){
                                            if(chatInfo.id == finalInviteLink.chat_id){
                                                targetChatInfo = chatInfo;
                                                break;
                                            }
                                        }
                                    }
                                    RequestData<ChatInviteLink> requestData =  new RequestData<ChatInviteLink>("已是群成员");
                                    if(targetChatInfo!=null){
                                        finalInviteLink.chatInfo = targetChatInfo;
                                        requestData.data = finalInviteLink;
                                    }
                                    resultBlock.onResult(request, response,requestData);
                                }else{
                                    resultBlock.onResult(request, response, null);
                                }
                            }

                            @Override
                            public void onTimeout(Map<String, Object> request1) {
                                resultBlock.onResult(request, response, null);
                            }
                        });
                    }else{
                        resultBlock.onResult(request, response, null);
                    }

                } else {
                    ChatInviteLink inviteLink = new Gson().fromJson(response, ChatInviteLink.class);
                    if(inviteLink!=null&&isNull(inviteLink.member_user_ids)&&inviteLink.chat_id!=0){
                        TelegramManager.getTelegramManager().getGroupMember(context, inviteLink.chat_id, UserInfo.getUserInfo().id, new TgResultBlock<GroupMemberInfo>() {
                            @Override
                            public void onResult(Map<String, Object> request1, JsonObject response1, GroupMemberInfo obj) {
                                if(obj!=null){
                                    List<ChatInfo> chatInfos = TelegramManager.getTelegramManager().getTgData().getChatList();
                                    ChatInfo targetChatInfo = null;
                                    if(chatInfos!=null&&chatInfos.size()>0){
                                        for(ChatInfo chatInfo:chatInfos){
                                            if(chatInfo.id == inviteLink.chat_id){
                                                targetChatInfo = chatInfo;
                                                break;
                                            }
                                        }
                                    }
                                    RequestData<ChatInviteLink> requestData =  new RequestData<ChatInviteLink>("已是群成员");
                                    if(targetChatInfo!=null){
                                        inviteLink.chatInfo = targetChatInfo;
                                        requestData.data = inviteLink;
                                    }
                                    resultBlock.onResult(request, response,requestData);
                                }else{
                                    resultBlock.onResult(request, response, new RequestData<ChatInviteLink>(inviteLink));
                                }
                            }

                            @Override
                            public void onTimeout(Map<String, Object> request1) {
                                resultBlock.onResult(request, response, new RequestData<ChatInviteLink>(inviteLink));
                            }
                        });
                    }else{
                        resultBlock.onResult(request, response, new RequestData<ChatInviteLink>(inviteLink));
                    }

                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    private static boolean isNull(List<Long> list){
        return list==null||list.size()==0;
    }



    private String tansferInviteLink(String invite_link){
        if(TextUtils.isEmpty(invite_link)){
            return "";
        }
        if(invite_link.contains(Constants.GROUP_SHARE_LINK_PRE_TEXT)){
            return invite_link;
        }
        try {
            Uri uri = Uri.parse(invite_link);
            String link = uri.getQueryParameter("link");
            return Constants.GROUP_SHARE_LINK_PRE_TEXT+link;
        }catch (Exception e){
            e.printStackTrace();
        }
        return invite_link;
    }


    /**
     * 生成群链接邀请
     */
    public void joinChatByInviteLink(Context context, String invite_link,boolean isTransferLink, TgResultBlock<ChatInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "joinChatByInviteLink");
        funMap.put("invite_link", isTransferLink?tansferInviteLink(invite_link):invite_link);
        funMap.put("@extra", rtId);
        addTask("joinChatByInviteLink", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    ChatInfo chatInfo = new Gson().fromJson(response, ChatInfo.class);
                    resultBlock.onResult(request, response, chatInfo);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void joinChat(Context context,long chatId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "joinChat");
        funMap.put("chat_id", chatId);
        funMap.put("@extra", rtId);
        addTask("joinChat", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    String errorMsg = errorMsg(response);
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取联系人信息
     *
     * @param userId      用户id
     * @param resultBlock 回调
     */
    public void requestContactInfo(Context context, long userId, TgResultBlock<UserInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getUser");
        funMap.put("user_id", userId);
        funMap.put("@extra", rtId);
        addTask("requestContactInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    //内部逻辑处理，加入缓存
                    parseUserInfo(response);
                    //正常返回
                    UserInfo info = new Gson().fromJson(response, UserInfo.class);
                    resultBlock.onResult(request, response, info);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void getUserFullInfo(Context context, long userId, TgResultBlock<UserFullInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getUserFullInfo");
        funMap.put("user_id", userId);
        funMap.put("@extra", rtId);
        addTask("getUserFullInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    //正常返回
                    UserFullInfo info = new Gson().fromJson(response, UserFullInfo.class);
                    resultBlock.onResult(request, response, info);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取联系人详细信息
     *
     * @param userId      用户id
     * @param resultBlock 回调
     */
    public void requestContactFullInfo(Context context, long userId, TgResultBlock<UserFullInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getChat");
        funMap.put("chat_id", userId);
        funMap.put("@extra", rtId);
        addTask("requestContactFullInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    UserFullInfo info = new Gson().fromJson(response, UserFullInfo.class);
                    resultBlock.onResult(request, response, info);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void requestChatInfoByChatId(Context context, long chatId, TgResultBlock<ChatInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getChat");
        funMap.put("chat_id", chatId);
        funMap.put("@extra", rtId);
        addTask("requestContactFullInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    ChatInfo info = new Gson().fromJson(response, ChatInfo.class);
                    resultBlock.onResult(request, response, info);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取联系人原始详细信息
     *
     * @param userId      用户id
     * @param resultBlock 回调
     */
    public void requestOrgContactInfo(Context context, long userId, TgResultBlock<OrgUserInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("uIds", new ArrayList<>(Arrays.asList(userId)));
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "users.info");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("requestOrgContactInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonArray list = customResultListData(response, true);
                List<OrgUserInfo> userList = null;
                if (list != null) {
                    userList = new Gson().fromJson(list, new TypeToken<List<OrgUserInfo>>() {
                    }.getType());
                }
                if (userList != null && userList.size() > 0) {
                    resultBlock.onResult(request, response, userList.get(0));
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getUserInfoEx(Context context,TgResultBlock<UserMyInfo> resultBlock) {
        getUserInfoEx(context,0,resultBlock);
    }


    public void getUserInfoEx(Context context,long userId,TgResultBlock<UserMyInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();

        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        if(userId!=0){
            Map<String, Object> parameters = new HashMap<>();
            parameters.put("userId", userId);
            funMap.put("parameters", new Gson().toJson(parameters));
        }
        funMap.put("method", "users.getUserInfoExt");
        funMap.put("@extra", rtId);
        addTask("users.getUserInfoExt", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject jsonObject = customResultData(response);
                UserMyInfo userMyInfo = new Gson().fromJson(jsonObject,UserMyInfo.class);
                if (userMyInfo!=null) {
                    if(TextUtils.isEmpty(userMyInfo.country)&&"CN".equals(userMyInfo.countryCode)){
                        userMyInfo.country = App.getInstanse().getString(R.string.china_text);
                    }
                    resultBlock.onResult(request, response, userMyInfo);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void setUserInfoExt(Context context,UserMyInfo userMyInfo,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()||userMyInfo==null) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "users.setUserInfoExt");
        funMap.put("parameters", new Gson().toJson(userMyInfo));
        funMap.put("@extra", rtId);
        addTask("users.setUserInfoExt", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, ""));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void requestOrgContactInfos(Context context, List<Long> userIds, TgResultBlock<List<OrgUserInfo>> resultBlock) {
        if (!getTgData().isValid() || userIds.isEmpty()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("uIds", userIds);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "users.info");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("requestOrgContactInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonArray list = customResultListData(response, true);
                List<OrgUserInfo> userList = null;
                if (list != null) {
                    userList = new Gson().fromJson(list, new TypeToken<List<OrgUserInfo>>() {
                    }.getType());
                }
                if (userList != null && userList.size() > 0) {
                    resultBlock.onResult(request, response, userList);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getUserPrivacySettingRules(Context context,UserPrivacySetting setting,TgResultBlock<UserPrivacySettingRules> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getUserPrivacySettingRules");
        funMap.put("setting", setting);
        funMap.put("@extra", rtId);
        addTask("getUserPrivacySettingRules", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                resultBlock.onResult(request, response, new Gson().fromJson(response, UserPrivacySettingRules.class));
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void setUserPrivacySettingRules(Context context, UserPrivacySetting setting, UserPrivacySettingRules rules,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }

        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setUserPrivacySettingRules");
        funMap.put("setting", setting);
        funMap.put("rules", rules);
        funMap.put("@extra", rtId);
        addTask("setUserPrivacySettingRules", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取黑名单列表
     *
     * @param resultBlock 回调
     */
    public void requestblockedUserList(Context context, TgResultBlock<List<MessageSendUser>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getBlockedMessageSenders");
        funMap.put("offset", 0);
        funMap.put("limit", 100);
        funMap.put("@extra", rtId);
        addTask("requestblockedUserList", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<MessageSendUser> ids = null;
                if (response != null && response.has("senders")) {
                    if (!isResultError(response)) {
                        JsonArray sendUsers = response.getAsJsonArray("senders");
                        if (sendUsers != null) {
                            ids = new Gson().fromJson(sendUsers, new TypeToken<List<MessageSendUser>>() {
                            }.getType());
                        }
                    }
                }
                resultBlock.onResult(request, response, ids);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="音视频通话相关">

    /**
     * 生成声网token
     *
     * @param channelName 频道名称
     * @param uid         用户id
     * @param resultBlock 回调 - rtc token
     */
    public void createRtcToken(Context context, String channelName, long uid, TgResultBlock<String> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("channelName", channelName);
        parameters.put("uid", uid);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "call.token.create");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("createRtcToken", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                if (data != null && data.has("token")) {
                    resultBlock.onResult(request, response, data.get("token").getAsString());
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 创建新通话
     *
     * @param callInfo    通话信息
     * @param resultBlock 回调
     */
    public void createCall(Context context, CallBaseInfo callInfo, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "call.create");
        funMap.put("parameters", new Gson().toJson(callInfo));
        funMap.put("@extra", rtId);
        addTask("createCall", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                int code = customResultCode(response);
                if (data != null && data.has("callId")) {
                    resultBlock.onResult(request, response, new TgResponse(true, code, "创建成功", data.get("callId").getAsLong()));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, code, "创建失败"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 确认收到
     *
     * @param callId      通话id
     * @param resultBlock 回调
     */
    public void callInviteAsk(Context context, long callId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("callId", callId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "call.ack.invite");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("callInviteAsk", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "请求成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "请求失败"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 通话取消-仅发起人可以调用
     *
     * @param callId      通话id
     * @param resultBlock 回调
     */
    public void cancelCall(Context context, long callId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("callId", callId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "call.cancel");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("cancelCall", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "请求成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "请求失败"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 加入/开始通话
     *
     * @param callId      通话id
     * @param resultBlock 回调
     */
    public void startCall(Context context, long callId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("callId", callId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "call.start");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("startCall", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "请求成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "请求失败"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 离开/停止通话
     *
     * @param callId      通话id
     * @param resultBlock 回调
     */
    public void stopCall(Context context, long callId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("callId", callId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "call.stop");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("stopCall", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "请求成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "请求失败"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取离线通话记录
     *
     * @param resultBlock 回调
     */
    public void queryOfflineCall(Context context, TgResultBlock<List<RemoteCallInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("timeOut", 30);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "call.queryOffline");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("queryOfflineCall", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                List<RemoteCallInfo> callList = null;
                if (data != null && data.has("records")) {
                    JsonArray list = data.getAsJsonArray("records");
                    if (list != null) {
                        callList = new Gson().fromJson(list, new TypeToken<List<RemoteCallInfo>>() {
                        }.getType());
                    }
                }
                resultBlock.onResult(request, response, callList);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 分页获取通话记录
     *
     * @param context
     * @param type        0:单聊呼出和接听(所有通话)、1 单聊呼出 、2单聊接听 、3会议
     * @param page        获取第N页，从1开始
     * @param count       每页数量
     * @param resultBlock
     */
    public void queryHistoryCall(Context context, int type, int page, int count, TgResultBlock<List<RemoteCallInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("type", type);
        parameters.put("page", page);
        parameters.put("count", count);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "call.queryRecord");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("queryHistoryCall", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonArray list = customResultListData(response, false);
                List<RemoteCallInfo> callList = null;
                if (list != null) {
                    callList = new Gson().fromJson(list, new TypeToken<List<RemoteCallInfo>>() {
                    }.getType());
                }
                resultBlock.onResult(request, response, callList);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="红包相关">

    /**
     * 创建红包
     *
     * @param rpInfo      红包信息
     * @param resultBlock 回调
     *                    TgResponse.errCode
     *                    400:余额少于红包总金额
     *                    401:红包数量大于1000
     *                    402:单个红包金额少于0.01
     *                    403:单个红包金额大于200
     *                    404:支付密码错误
     */
    public void createRp(Context context, RedPacketInfo rpInfo, TgResultBlock<TgResponse> resultBlock) {
        if (rpInfo == null) {
            return;
        }
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "redpacket.create");
        funMap.put("parameters", new Gson().toJson(rpInfo));
        funMap.put("@extra", rtId);
        addTask("createRp", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "创建成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "红包创建失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 请求红包详情
     *
     * @param rpId        红包id
     * @param resultBlock 回调
     */
    public void queryRp(Context context, long rpId, TgResultBlock<RedPacketInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("redPacketId", rpId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "redpacket.detail");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("queryRp", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                if (data != null) {
                    RedPacketInfo info = new Gson().fromJson(data, RedPacketInfo.class);
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 领取红包
     *
     * @param rpId        红包id
     * @param resultBlock 回调
     *                    TgResponse.errCode
     *                    400 不能领取自己的红包
     *                    401 没有权限领取该红包
     *                    402 红包被抢光了
     *                    TgResponse.data = List<RedPacketPickUser>最新的领取用户列表
     */
    public void gotRp(Context context, long rpId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("redPacketId", rpId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "redpacket.get");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("gotRp", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                JsonArray list = customResultListData(response, true);
                List<RedPacketPickUser> gotUsersList = null;
                if (list != null) {
                    gotUsersList = new Gson().fromJson(list, new TypeToken<List<RedPacketPickUser>>() {
                    }.getType());
                }
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "领取成功", gotUsersList));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "领取失败", gotUsersList));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void createTransferMoney(Context context, RemittanceInfo info, TgResultBlock<TgResponse> resultBlock) {
        if (info == null) {
            return;
        }
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "remittance.remit");
        funMap.put("parameters", new Gson().toJson(info));
        funMap.put("@extra", rtId);
        addTask("remittanceRemit", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "转账成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "转账失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 接收转账
     * @param context
     * @param remittanceId
     * @param resultBlock
     */
    public void reciveTransferMoney(Context context, long remittanceId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "remittance.receive");
        HashMap<String,Object> hashMap = new HashMap<>();
        hashMap.put("remittanceId",remittanceId);
        funMap.put("parameters", new Gson().toJson(hashMap));
        funMap.put("@extra", rtId);
        addTask("remittanceReceive", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "接收转账成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "接收转账失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 提醒接收转账
     * @param context
     * @param remittanceId
     * @param resultBlock
     */
    public void hintTransferMoney(Context context, long remittanceId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "remittance.remind");
        HashMap<String,Object> hashMap = new HashMap<>();
        hashMap.put("remittanceId",remittanceId);
        funMap.put("parameters", new Gson().toJson(hashMap));
        funMap.put("@extra", rtId);
        addTask("remittanceRemind", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "提醒接收转账成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "提醒接收转账失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void refundTransferMoney(Context context, long remittanceId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "remittance.refund");
        HashMap<String,Object> hashMap = new HashMap<>();
        hashMap.put("remittanceId",remittanceId);
        funMap.put("parameters", new Gson().toJson(hashMap));
        funMap.put("@extra", rtId);
        addTask("createRp", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "退款成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "退款失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void queryTransferMoney(Context context, long remittanceId, TgResultBlock<RemittanceDetailInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("remittanceId", remittanceId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "remittance.getRecord");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("queryRp", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                if (data != null) {
                    RemittanceDetailInfo info = new Gson().fromJson(data, RemittanceDetailInfo.class);
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 查询钱包详情
     *
     * @param resultBlock 回调
     */
    public void queryWalletInfo(Context context, TgResultBlock<WalletInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "wallet.info");
        funMap.put("parameters", "{}");
        funMap.put("@extra", rtId);
        addTask("queryWalletInfo", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                if (data != null) {
                    WalletInfo info = new Gson().fromJson(data, WalletInfo.class);
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 设置钱包支付密码
     *
     * @param password    密码(md5) 使用Common.MD5()方法
     * @param smsCode     短信
     * @param resultBlock 回调
     *                    TgResponse.errCode
     *                    400 短信验证码错误
     */
    public void setWalletPayPassword(Context context, String oldPassword,String newPassword, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        if(!TextUtils.isEmpty(oldPassword)){
            parameters.put("old_password", Common.MD5(oldPassword));
        }
        parameters.put("new_password", Common.MD5(newPassword));
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.account.setWalletPassword");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("setWalletPayPassword", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "钱包密码设置成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, "钱包密码设置失败，请稍后重试(" + resCode + ")"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void checkWalletPayPassword(Context context, String password, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("password", Common.MD5(password));
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.account.checkWalletPassword");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("checkWalletPassword", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "密码校验成功"));
                } else {
                    String errorMsg = "密码校验失败";
                    if(resCode == 400){
                        errorMsg = "密码无效";
                    }else if(resCode == 401){
                        errorMsg = "密码错误";
                    }
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, errorMsg));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 分页获取钱包交易记录
     *
     * @param count       数量
     * @param page        页码，从1开始
     * @param resultBlock 回调
     */
    public void queryWalletOrderListCall(Context context, int count, int page, TgResultBlock<List<WalletOrderInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("count", count);
        parameters.put("page", page);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "wallet.records");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("queryWalletOrderListCall", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonArray list = customResultListData(response, false);
                List<WalletOrderInfo> orderList = null;
                if (list != null) {
                    orderList = new Gson().fromJson(list, new TypeToken<List<WalletOrderInfo>>() {
                    }.getType());
                }
                resultBlock.onResult(request, response, orderList);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 分页获取红包记录
     *
     * @param type        1创建红包 2领取红包
     * @param count       数量
     * @param page        页码
     * @param resultBlock 回调
     */
    public void queryRedHistoryCall(Context context, int type, int count, int page, TgResultBlock<List<RedPacketInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("type", type);
        parameters.put("count", count);
        parameters.put("page", page);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "redpacket.record");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("queryRedHistoryCall", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonArray list = customResultListData(response, false);
                List<RedPacketInfo> redList = null;
                if (list != null) {
                    redList = new Gson().fromJson(list, new TypeToken<List<RedPacketInfo>>() {
                    }.getType());
                }
                resultBlock.onResult(request, response, redList);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 充值信息获取
     *
     * @param resultBlock 回调
     */
    public void WalletRechargeRequest(Context context, TgResultBlock<WalletRechargeRes> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.recharge");
        funMap.put("parameters", "{}");
        funMap.put("@extra", rtId);
        addTask("WalletRechargeRequest", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                if (data != null) {
                    WalletRechargeRes info = new Gson().fromJson(data, WalletRechargeRes.class);
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 提现信息获取
     *
     * @param amount      金额
     * @param resultBlock 回调 - data WalletTixianRes
     *                    400:余额不足
     *                    401:钱包密码错误
     *                    402:钱包密码未设置
     */
    public void WalletTixianRequest(Context context, float amount, String password, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("amount", amount);
        parameters.put("password", password);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.withdraw");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("WalletTixianRequest", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                int resCode = customResultCode(response);
                if (resCode == 200 && data != null) {
                    WalletTixianRes info = new Gson().fromJson(data, WalletTixianRes.class);
                    resultBlock.onResult(request, response, new TgResponse(true, resCode, "", info));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, resCode, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 查询第三方充值通道
     *
     * @param resultBlock 回调
     */
    public void queryThirdRechargeChannels(Context context, TgResultBlock<ThirdRechargeChannelInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "wallet.getThirdChannels");
        funMap.put("parameters", "{}");
        funMap.put("@extra", rtId);
        addTask("queryThirdRechargeChannels", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                if (data != null) {
                    ThirdRechargeChannelInfo info = new Gson().fromJson(data, ThirdRechargeChannelInfo.class);
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="配置相关">

    /**
     * 获取发现页菜单分组列表
     *
     * @param resultBlock 回调
     */
    public void queryDiscoverSections(Context context, TgResultBlock<List<DiscoverMenuSectionInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.discover");
        funMap.put("parameters", "{}");
        funMap.put("@extra", rtId);
        addTask("queryDiscoverSections", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonArray list = customResultListData(response, false);
                List<DiscoverMenuSectionInfo> orderList = null;
                if (list != null) {
                    orderList = new Gson().fromJson(list, new TypeToken<List<DiscoverMenuSectionInfo>>() {
                    }.getType());
                }
                resultBlock.onResult(request, response, orderList);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取tab扩展菜单
     *
     * @param resultBlock 回调
     */
    public void queryTabExMenu(Context context, TgResultBlock<TabExMenuInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.system.getCustomMenus");
        funMap.put("parameters", "{}");
        funMap.put("@extra", rtId);
        addTask("queryTabExMenu", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (customResultCode(response) == 200) {
                    TabExMenuInfo info = new TabExMenuInfo();
                    JsonObject data = customResultData(response);
                    if (data != null) {
                        info = new Gson().fromJson(data, TabExMenuInfo.class);
                    }
                    resultBlock.onResult(request, response, info);
                } else {
                    resultBlock.onResult(request, response, null);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void registerDevice(Context context, String registrationId,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("@type","deviceTokenSimplePush");
        parameters.put("endpoint",registrationId);

        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "registerDevice");
        funMap.put("device_token", parameters);
        funMap.put("@extra", rtId);
        addTask("registerDevice", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                resultBlock.onResult(request, response, null);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    /**
     * 获取app配置信息
     *
     * @param resultBlock 回调
     */
    public void queryAppConfig(Context context, TgResultBlock<AppConfigInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.system.getAppConfig");
        funMap.put("parameters", "{}");
        funMap.put("@extra", rtId);
        addTask("queryAppConfig", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                AppConfigInfo info = null;
                JsonObject data = customResultData(response);
                if (data != null) {
                    info = new Gson().fromJson(data, AppConfigInfo.class);
                }
                resultBlock.onResult(request, response, info);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    /**
     * 获取用户信息
     *
     * @param resultBlock 回调
     */
    public void queryUserMyInfo(Context context, TgResultBlock<UserMyInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.account.myInfo");
        funMap.put("parameters", "{}");
        funMap.put("@extra", rtId);
        addTask("queryAppConfig", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                UserMyInfo info = null;
                JsonObject data = customResultData(response);
                if (data != null) {
                    info = new Gson().fromJson(data, UserMyInfo.class);
                }
                resultBlock.onResult(request, response, info);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 修改/设置登录密码
     *
     * @param resultBlock 回调
     */
    public void alterLoginPassword(Context context, String oldPassword,String newPassword,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }

        Map<String, Object> parameters = new HashMap<>();
        if(!TextUtils.isEmpty(oldPassword)){
            parameters.put("old_password", Common.MD5(oldPassword));
//            parameters.put("old_password", oldPassword);
        }
        parameters.put("new_password", newPassword);
//        parameters.put("new_password", Common.MD5(newPassword));
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.account.setPassword");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("queryAppConfig", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, "设置密码成功"));
                } else {
                    String errorMsg;
                    if(resCode==400){
                        errorMsg = "无效新密码";
                    }else if(resCode == 401){
                        errorMsg = "旧密码错误";
                    }else{
                        errorMsg = "设置密码失败，请稍后重试";
                    }
                    resultBlock.onResult(request, response, new TgResponse(false,errorMsg));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取app配置信息
     *
     * @param resultBlock 回调
     */
    public void queryAppConfigWithoutLogin() {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getApplicationConfig");
        funMap.put("@extra", rtId);
        addTask("getApplicationConfig", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                AppConfigInfo appConfigInfo = null;
                if(!isResultError(response)){
                    try {
                        JsonArray jsonArray = response.getAsJsonArray("members");
                        if(jsonArray!=null&&jsonArray.size()>0){
                            appConfigInfo = new AppConfigInfo();
                            for(JsonElement jsonElement:jsonArray){
                                if(jsonElement.isJsonObject()){
                                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                                    String key = jsonObject.get("key").getAsString();
                                    if(!TextUtils.isEmpty(key)&&jsonObject.get("value").isJsonObject()){
                                        if("password_flood_interval".equals(key)){
                                            int isInnerValue = jsonObject.getAsJsonObject("value").get("value").getAsInt();
                                            appConfigInfo.password_flood_interval = isInnerValue;
                                        }else{
                                            boolean isInnerValue = jsonObject.getAsJsonObject("value").get("value").getAsBoolean();
                                            if("phone_code_login".equals(key)){
                                                appConfigInfo.phone_code_login = isInnerValue;
                                            }else if("register_need_phone_code".equals(key)){
                                                appConfigInfo.register_need_phone_code = isInnerValue;
                                            }else if("register_need_inviter".equals(key)){
                                                appConfigInfo.register_need_inviter = isInnerValue;
                                            }else if("using_oss".equals(key)){
                                                appConfigInfo.using_oss = isInnerValue;
                                            }else if("can_send_file".equals(key)){
                                                appConfigInfo.can_send_file = isInnerValue;
                                            }else if("shown_everyone_member_changes".equals(key)){
                                                appConfigInfo.shown_everyone_member_changes = isInnerValue;
                                            }else if("enabled_screenshot_notification".equals(key)){
                                                appConfigInfo.enabled_screenshot_notification = isInnerValue;
                                            }else if("shown_online_members".equals(key)){
                                                appConfigInfo.shown_online_members = isInnerValue;
                                            }else if("enabled_destroy_after_reading".equals(key)){
                                                appConfigInfo.enabled_destroy_after_reading = isInnerValue;
                                            }else if("can_send_location".equals(key)){
                                                appConfigInfo.can_send_location = isInnerValue;
                                            }else if("can_send_redpacket".equals(key)){
                                                appConfigInfo.can_send_redpacket = isInnerValue;
                                            }else if("can_remit".equals(key)){
                                                appConfigInfo.can_remit = isInnerValue;
                                            }else if("can_see_address_book".equals(key)){
                                                appConfigInfo.can_see_address_book = isInnerValue;
                                            }else if("can_see_blog".equals(key)){
                                                appConfigInfo.can_see_blog = isInnerValue;
                                            }else if("can_invite_friend".equals(key)){
                                                appConfigInfo.can_invite_friend = isInnerValue;
                                            }else if("can_see_nearby".equals(key)){
                                                appConfigInfo.can_see_nearby = isInnerValue;
                                            }else if("can_see_public_group".equals(key)){
                                                appConfigInfo.can_see_public_group = isInnerValue;
                                            }else if("can_see_qr_code".equals(key)){
                                                appConfigInfo.can_see_qr_code = isInnerValue;
                                            }else if("can_see_wallet".equals(key)){
                                                appConfigInfo.can_see_wallet = isInnerValue;
                                            }else if("can_see_wallet_records".equals(key)){
                                                appConfigInfo.can_see_wallet_records = isInnerValue;
                                            }else if("can_see_emoji_shop".equals(key)){
                                                appConfigInfo.can_see_emoji_shop = isInnerValue;
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }catch (Exception e){

                    }

                }
                if (appConfigInfo != null) {
                    AppConfigInfo.saveAppWithoutLoginConfigInfo(appConfigInfo);

                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_App_All_Config_Changed, null));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
            }
        });
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="公共">

    /**
     * 验证当前登录手机号验证码
     *
     * @param type        用途类型
     * @param resultBlock
     */
    public void verifySmsCode(Context context, SmsCodeType type,String code ,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("type", type == SmsCodeType.SmsCodeType_SetWalletPassword ? 1 : type == SmsCodeType.SmsCodeType_DeleteAccount?3:0);
        parameters.put("code",code);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "system.verifySmsCode");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("verifySmsCode", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, "验证验证码成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, "验证验证码失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void verifyPassword(Context context, String password ,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "checkPassword");
        funMap.put("password", password);
        funMap.put("@extra", rtId);
        addTask("verifyPassword", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (!isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(true, "验证密码成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, "验证密码失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }



    public void gotSmsCode(Context context, SmsCodeType type, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("type", type == SmsCodeType.SmsCodeType_SetWalletPassword ? 1 : type == SmsCodeType.SmsCodeType_DeleteAccount?3:0);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "system.sendSmsCode");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("gotSmsCode", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                int resCode = customResultCode(response);
                if (resCode == 200) {
                    resultBlock.onResult(request, response, new TgResponse(true, "获取验证码成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, "获取验证码失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void sendChatAction(long chat_id) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> actionMap = new HashMap<>();
        actionMap.put("@type", "chatActionTyping");
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendChatAction");
        funMap.put("chat_id", chat_id);
        funMap.put("message_thread_id", 0);
        funMap.put("action", actionMap);
        funMap.put("@extra", rtId);
        addTask("sendChatAction", rtId, funMap, new TgResultBlock<Object>() {

            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {

            }

            @Override
            public void onTimeout(Map<String, Object> request) {

            }
        });
    }


    public void getGroupsInCommon(Context context, long user_id,long offset_chat_id,int limit, TgResultBlock<ChatsInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getGroupsInCommon");
        funMap.put("user_id", user_id);
        funMap.put("offset_chat_id", offset_chat_id);
        funMap.put("limit", limit);
        funMap.put("@extra", rtId);
        addTask("getGroupsInCommon", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, null);
                } else {
                    ChatsInfo chatsInfo = new Gson().fromJson(response, ChatsInfo.class);
                    resultBlock.onResult(request, response, chatsInfo);
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    /**
     * 获取app版本
     *
     * @param context
     * @param versionCode 版本code
     * @param resultBlock 回调，errCode=201:已是最新版本
     */
    public void getAppVersion(Context context, int versionCode, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("platform", "android");
        parameters.put("versionCode", versionCode);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.app.getVersion");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("getAppVersion", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonObject data = customResultData(response);
                if (data != null) {
                    AppVersionInfo info = new Gson().fromJson(data, AppVersionInfo.class);
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "有新版本", info));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, customResultCode(response), ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getOnlineUserService(Context context, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "web.system.getCSNumbers");
        funMap.put("parameters", "{}");
        funMap.put("@extra", rtId);
        addTask("getOnlineUserService", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                JsonArray list = customResultListData(response, false);
                if (list != null && list.size() > 0) {
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "存在客服", list.get(0).getAsLong()));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, "无在线客服"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="文件相关">

    /**
     * 判断文件是否正在下载
     *
     * @param fileId - 文件id
     * @param type   - 文件类型
     * @return true表示正在下载
     */
    public boolean isFileDownloading(long fileId, FileType type) {
        String keyString = FileTaskInfo.fileTaskKey(type, fileId);
        FileTaskInfo taskInfo = tgData.fileTaskInfo(keyString);
        if(taskInfo!=null&&java.lang.System.currentTimeMillis() - taskInfo.timestamp>3*1000){
            cancelDownloadFile(fileId);
            tgData.removeFileTask(keyString);
            return false;
        }else{
            return taskInfo != null;
        }
//        return tgData.fileTaskInfo(keyString)!=null;
    }

    /**
     * 下载文件，下载结果通过EventBus方式分发，具体见EUser_TgEvent文件部分定义
     *
     * @param id              标识符，userinfo，使用id; chatinfo，使用id; MessageInfo,使用id
     * @param fileId          文件id
     * @param download_offset 目前填0即可
     * @param type            文件类型
     */
    public void downloadFile(String id, long fileId, long download_offset, FileType type) {
        downloadFile(id,fileId,download_offset,type== FileType.FileType_Message_Video?1024:0,type);
    }
   public void downloadVoice(String id, long fileId, long download_offset, FileType type) {
        downloadFile(id,fileId,download_offset,type== FileType.FileType_Message_Voice?1024:0,type);
    }

    public void downloadFile(String id, long fileId, long download_offset,long limit ,FileType type) {
        if(!SettingManager.getInstance().canDownload(type)){
            return;
        }
        if (StringUtils.isEmpty(id)) {
            return;
        }
        if (!getTgData().isValid()) {
            return;
        }
        if (!isFileDownloading(fileId, type)) {
            String keyString = FileTaskInfo.fileTaskKey(type, fileId);
            FileTaskInfo task = new FileTaskInfo();
            task.id = id;
            task.file_id = fileId;
            task.fileType = type;
            tgData.addFileTask(keyString, task);

            //准备请求报文
            int rtId = getTgData().getNextRequestId();
            Map<String, Object> funMap = new HashMap<>();
            funMap.put("@type", "downloadFile");
            funMap.put("file_id", fileId);
            funMap.put("priority", task.priority());
            funMap.put("offset", download_offset);
            funMap.put("limit", limit);
            funMap.put("synchronous", true);

            funMap.put("@extra", rtId);
            addTask("DownloadFile", rtId, false,type == FileType.FileType_Message_Video?3*1000:ACK_TIME_OUT, funMap, new TgResultBlock<Object>() {
                @Override
                public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                    if (type==FileType.FileType_Message_Voice){
                        LogUtils.e("测试下载，下载完成");
                    }
                    downloadFileComplete(id,fileId,download_offset,type,task, response);

                }

                @Override
                public void onTimeout(Map<String, Object> request) {
//                    cancelDownloadFile(fileId, new TgResultBlock<Object>() {
//
//                        @Override
//                        public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
//                            tgData.removeFileTask(task.fileTaskKey());
//                            downloadFile(id,fileId,download_offset,type);
//                        }
//
//                        @Override
//                        public void onTimeout(Map<String, Object> request) {
//                            tgData.removeFileTask(task.fileTaskKey());
//                            downloadFile(id,fileId,download_offset,type);
//                        }
//                    });
                    if (type==FileType.FileType_Message_Voice){
                        LogUtils.e("测试下载，下载超时");
                    }
                    tgData.removeFileTask(task.fileTaskKey());
                    downloadFile(id,fileId,download_offset,type);
                }
            });
        }else{
//            if(type == FileType.FileType_Message_Video){
//                DownloadVideoManager.getIntance().enqueue(new DownloadTask(id,fileId,download_offset));
//            }

        }
    }


    public void downloadVideoFile(long fileId, long download_offset,int limit,TgResultBlock<byte[]> tgResultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        FileType type = FileType.FileType_Message_Video;
        if (!isFileDownloading(fileId, type)) {
            String keyString = FileTaskInfo.fileTaskKey(type, fileId);
            FileTaskInfo task = new FileTaskInfo();
            task.id = String.valueOf(fileId);
            task.file_id = fileId;
            task.fileType = type;
            tgData.addFileTask(keyString, task);

            //准备请求报文
            int rtId = getTgData().getNextRequestId();
            Map<String, Object> funMap = new HashMap<>();
            funMap.put("@type", "downloadFile");
            funMap.put("file_id", fileId);
            funMap.put("priority", task.priority());
            funMap.put("offset", download_offset);
            funMap.put("limit", limit);
            funMap.put("synchronous", true);
            funMap.put("@extra", rtId);
            addTask("DownloadFile", rtId, true, funMap, new TgResultBlock<Object>() {
                @Override
                public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                    readFilePart(fileId,download_offset,limit,tgResultBlock);
                }

                @Override
                public void onTimeout(Map<String, Object> request) {
                    tgResultBlock.onTimeout(request);
                }
            });
        }
    }

    public void readFilePart(long fileId,long offset,int count,TgResultBlock<byte[]> tgResultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "readFilePart");
        funMap.put("file_id", fileId);
        funMap.put("offset", offset);
        funMap.put("count", count);
        funMap.put("@extra", rtId);
        addTask("readFilePart", rtId, true, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if(response!=null&&response.get("data")!=null){
                    tgResultBlock.onResult(request,response,Base64.decode(response.get("data").getAsString(),Base64.DEFAULT));
                }else{
                    tgResultBlock.onResult(request,response,null);
                }

            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                tgResultBlock.onTimeout(request);
            }
        });
    }

    public void cancelDownloadFile(long fileId) {
        cancelDownloadFile(fileId,new TgResultBlock<Object>() {

            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {

            }

            @Override
            public void onTimeout(Map<String, Object> request) {

            }
        });
    }

    public void cancelDownloadFile(long fileId,TgResultBlock<Object> tgResultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "cancelDownloadFile");
        funMap.put("only_if_pending", false);
        funMap.put("file_id", fileId);
        funMap.put("@extra", rtId);
        addTask("cancelDownloadFile", rtId, true, funMap, tgResultBlock);
    }


    public void getFile(long fileId,TgResultBlock<FileInfo> tgResultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getFile");
        funMap.put("file_id", fileId);
        funMap.put("@extra", rtId);
        addTask("readFilePart", rtId, true, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if(response!=null){
                    FileInfo fileInfo = new Gson().fromJson(response, FileInfo.class);
                    tgResultBlock.onResult(request,response,fileInfo);
                }else{
                    tgResultBlock.onResult(request,response,null);
                }

            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                tgResultBlock.onTimeout(request);
            }
        });
    }



    public void deleteFile(String id, long fileId, long download_offset, FileType type) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "deleteFile");
        funMap.put("file_id", fileId);
        funMap.put("@extra", rtId);
        addTask("DownloadFile", rtId, true, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                downloadFile(id,fileId,0,type);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {

            }
        });
    }

    public void deleteFile(long fileId) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "deleteFile");
        funMap.put("file_id", fileId);
        funMap.put("@extra", rtId);
        addTask("DownloadFile", rtId, true, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
            }

            @Override
            public void onTimeout(Map<String, Object> request) {

            }
        });
    }

    private void downloadFileComplete(String id, long fileId, long download_offset, FileType type,FileTaskInfo task, JsonObject response) {
        //从下载队列移除
        tgData.removeFileTask(task.fileTaskKey());
        if (response != null && response.has("@type")) {
            String fileType = response.get("@type").getAsString();
            if ("file".equals(fileType)) {
                FileInfo fileInfo = new Gson().fromJson(response, FileInfo.class);
                switch (task.fileType) {
                    case FileType_Photo:
                        contactPhotoDownloadComplete(task, fileInfo);
                        break;
                    case FileType_Group_Photo:
                        groupPhotoDownloadComplete(task, fileInfo);
                        break;
                    case FileType_Message_Photo:
                        messagePhotoDownloadComplete(task, fileInfo);
                        break;
                    case FileType_Message_Preview_Photo:
                        messagePreviewPhotoDownloadComplete(task, fileInfo);
                        break;
                    case FileType_Message_Video:
                        messageVideoDownloadComplete(task, fileInfo);
                        if(fileInfo!=null&&!fileInfo.isCompleted()){
                            downloadFile(id,fileId,fileInfo.downloadedStart(),type);
                        }
                        break;
                    case FileType_Message_Audio:
                        messageAudioDownloadComplete(task, fileInfo);
                        break;
                    case FileType_Message_Voice:
                        messageVoiceDownloadComplete(task, fileInfo);
                        break;
                    case FileType_Message_Document:
                        messageDocumentDownloadComplete(task, fileInfo);
                        break;
                    case FileType_Message_Animation:
                        messageAnimationDownloadComplete(task,fileInfo);
                        break;
                    default:
                        break;
                }
            } else {//下载失败

                switch (task.fileType) {
                    case FileType_Photo:
                        break;
                    case FileType_Group_Photo:
                        break;
                    case FileType_Message_Photo:
                        break;
                    case FileType_Message_Preview_Photo:
                        break;
                    case FileType_Message_Video:
                        downloadFile(id,fileId,download_offset,type);
                        break;
                    case FileType_Message_Audio:
                        break;
                    case FileType_Message_Voice:
                        break;
                    case FileType_Message_Document:
                        break;
                    case FileType_Message_Animation:

                        break;
                    default:
                        break;
                }
            }
        }

    }

    //联系人头像下载完成后的处理
    private void contactPhotoDownloadComplete(FileTaskInfo task, FileInfo fileInfo) {
        if (task != null && fileInfo != null && task.id != null) {
            long userId = Long.parseLong(task.id);
            UserInfo user = null;
            if (UserInfo.getUserInfo().id == userId) {
                user = UserInfo.getUserInfo();
            } else {
                user = tgData.contactInfo(userId);
            }
            if (user != null && user.profile_photo != null) {
                if (user.profile_photo.big != null && user.profile_photo.big.id == task.file_id) {
                    user.profile_photo.big = fileInfo;
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Contact_Photo_Ok, user));
                }
                if (user.profile_photo.small != null && user.profile_photo.small.id == task.file_id) {
                    user.profile_photo.small = fileInfo;
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Contact_Photo_Ok, user));
                }
            }
        }
    }

    //群组头像下载完成后的处理
    private void groupPhotoDownloadComplete(FileTaskInfo task, FileInfo fileInfo) {
        if (task != null && fileInfo != null && task.id != null) {
            ChatInfo chat = tgData.chatInfo(Long.parseLong(task.id));
            if (chat != null && chat.photo != null) {
                if (chat.photo.big != null && chat.photo.big.id == task.file_id) {
                    chat.photo.big = fileInfo;
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_Photo_Ok, chat));
                }
                if (chat.photo.small != null && chat.photo.small.id == task.file_id) {
                    chat.photo.small = fileInfo;
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Group_Photo_Ok, chat));
                }
            }
        }
    }

    //消息图片下载完成后的处理
    private void messagePhotoDownloadComplete(FileTaskInfo task, FileInfo file) {
        if (task != null && file != null) {
            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Message_Photo_Ok, task, file));
        }
    }

    //消息预览图片下载完成后的处理
    private void messagePreviewPhotoDownloadComplete(FileTaskInfo task, FileInfo file) {
        if (task != null && file != null) {
            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Message_Preview_Photo_Ok, task, file));
        }
    }

    //消息视频下载完成后的处理
    private void messageVideoDownloadComplete(FileTaskInfo task, FileInfo file) {
        if (task != null && file != null) {
            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Message_Video_Ok, task, file));
        }
    }

    //消息视频下载完成后的处理
    private void messageAnimationDownloadComplete(FileTaskInfo task, FileInfo file) {
        if (task != null && file != null) {
            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Message_Animation_Ok, task, file));
        }
    }

    //消息语音下载完成后的处理
    private void messageAudioDownloadComplete(FileTaskInfo task, FileInfo file) {
        if (task != null && file != null) {
            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Message_Audio_Ok, task, file));
        }
    }

    //消息语音下载完成后的处理
    private void messageVoiceDownloadComplete(FileTaskInfo task, FileInfo file) {
        if (task != null && file != null) {
            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Message_Voice_Ok, task, file));
        }
    }

    //消息文件下载完成后的处理
    private void messageDocumentDownloadComplete(FileTaskInfo task, FileInfo file) {
        if (task != null && file != null) {
            EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Message_Document_Ok, task, file));
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="通用解析">
    public static boolean isResultOk(JsonObject result) {
        if (result != null && result instanceof JsonObject) {
            if (result.has("@type")) {
                String type = result.get("@type").getAsString();
                if (!StringUtils.isEmpty(type)) {
                    return "ok".equals(type);
                }
            }
        }
        return false;
    }

    private static int customResultCode(JsonObject result) {
        if (result != null && result instanceof JsonObject) {
            if (result.has("@type")) {
                String type = result.get("@type").getAsString();
                if (!StringUtils.isEmpty(type) && "customRequestResult".equals(type)) {
                    if (result.has("result")) {
                        String resultStr = result.get("result").getAsString();
                        if (!StringUtils.isEmpty(resultStr)) {
                            JsonObject jsonObj = new Gson().fromJson(resultStr, JsonObject.class);
                            if (jsonObj != null && jsonObj.has("code")) {
                                return jsonObj.get("code").getAsInt();
                            }
                        }
                    }
                }
            }
        }
        return -1;
    }

    private static JsonObject customResultData(JsonObject result) {
        if (result != null && result instanceof JsonObject) {
            if (result.has("@type")) {
                String type = result.get("@type").getAsString();
                if (!StringUtils.isEmpty(type) && "customRequestResult".equals(type)) {
                    if (result.has("result")) {
                        String resultStr = result.get("result").getAsString();
                        if (!StringUtils.isEmpty(resultStr)) {
                            JsonObject jsonObj = new Gson().fromJson(resultStr, JsonObject.class);
                            if (jsonObj != null && jsonObj.has("code") && jsonObj.get("code").getAsInt() == 200) {
                                if (jsonObj.get("data")!=null&&jsonObj.get("data").isJsonObject())
                                    return jsonObj.getAsJsonObject("data");
                            }
                        }
                    }
                }
            }
        }
        return null;
    }


    private static JsonArray customResultListData(JsonObject result, boolean ignoreCode) {
        if (result != null && result instanceof JsonObject) {
            if (result.has("@type")) {
                String type = result.get("@type").getAsString();
                if (!StringUtils.isEmpty(type) && "customRequestResult".equals(type)) {
                    if (result.has("result")) {
                        String resultStr = result.get("result").getAsString();
                        if (!StringUtils.isEmpty(resultStr)) {
                            JsonObject jsonObj = new Gson().fromJson(resultStr, JsonObject.class);
                            if (jsonObj != null && jsonObj.has("code") && (ignoreCode || jsonObj.get("code").getAsInt() == 200)) {
                                if (jsonObj.get("data") != null && jsonObj.get("data").isJsonArray())
                                    return jsonObj.getAsJsonArray("data");
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    public static boolean isResultError(JsonObject result) {
        if (result != null && result instanceof JsonObject) {
            if (result.has("@type")) {
                String type = result.get("@type").getAsString();
                if (!StringUtils.isEmpty(type)) {
                    return "error".equals(type);
                }
            }
        }
        return false;
    }

    public static String errorMsg(JsonObject result) {
        if (result != null && result instanceof JsonObject) {
            if (result.has("@type")) {
                String type = result.get("@type").getAsString();
                if (!StringUtils.isEmpty(type)) {
                    if ("error".equals(type)) {
                        return String.format("%s_%s",
                                result.has("code") ? result.get("code").getAsString() : "",
                                result.has("message") ? result.get("message").getAsString() : "");
                    }
                }
            }
        }
        return "";
    }

    public static int errorCode(JsonObject result) {
        if (result != null && result instanceof JsonObject) {
            if (result.has("@type")) {
                String type = result.get("@type").getAsString();
                if (!StringUtils.isEmpty(type)) {
                    if ("error".equals(type)) {
                        return result.has("code") ? result.get("code").getAsInt() : -1;
                    }
                }
            }
        }
        return -1;
    }
    // </editor-fold>



    public void setUserState(boolean isOnline){
        if(!OuterShareActivity.isStartMain){
            return;
        }
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> valueMap = new HashMap<>();
        valueMap.put("@type","optionValueBoolean");
        valueMap.put("value",isOnline);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setOption");
        funMap.put("name", "online");
        funMap.put("value", valueMap);
        funMap.put("@extra", rtId);
        addTask("setUserOption", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {

            }

            @Override
            public void onTimeout(Map<String, Object> request) {

            }
        });
    }



    // <editor-fold defaultstate="collapsed" desc="朋友圈">

    /**
     * 查询动态
     *
     */
    public void getCircleHistory(Context context, CircleVisibleType type, long from_blog_id, int limit,TgResultBlock<BlogListInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getHistory");
        funMap.put("visible", type);
        funMap.put("from_blog_id",from_blog_id);
        funMap.put("limit",limit);
        funMap.put("offset",0);
        funMap.put("@extra", rtId);
        addTask("getCircleHistory", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogListInfo listInfo = null;
                try {
                    listInfo = new Gson().fromJson(response, BlogListInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, listInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void modifyPrivacyUsers(Context context, int key,boolean isAdding,List<Long> users,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("key",key);
        parameters.put("isAdding",isAdding);
        parameters.put("users",users);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "blogs.modifyPrivacyUsers");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("getCircleAllPrivacy", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (customResultCode(response) != 200) {
                    resultBlock.onResult(request, response, new TgResponse(false, "设置失败"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getCircleAllPrivacy(Context context, TgResultBlock<List<BlogPrivacyInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "blogs.getAllPrivacy");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("getCircleAllPrivacy", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                List<BlogPrivacyInfo> privacyInfos = null;
                try {
                    if(response.has("result")){
                        String result = response.get("result").getAsString();
                        JsonObject jsonObj = new Gson().fromJson(result, JsonObject.class);
                        if(jsonObj.has("code")&&jsonObj.get("code").getAsInt()==200){
                            if(jsonObj.has("data")&&jsonObj.get("data").isJsonObject()
                                    &&jsonObj.get("data").getAsJsonObject().has("privacyList")
                                    &&jsonObj.get("data").getAsJsonObject().get("privacyList").isJsonArray())
                                privacyInfos = new Gson().fromJson(jsonObj.get("data").getAsJsonObject().get("privacyList").getAsJsonArray(),new TypeToken<List<BlogPrivacyInfo>>(){}.getType());
                        }
                    }
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, privacyInfos);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void setCircleAllPrivacy(Context context, BlogPrivacyInfo privacyInfo,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("privacy",privacyInfo);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "blogs.setPrivacy");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("getCircleAllPrivacy", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (customResultCode(response) != 200) {
                    resultBlock.onResult(request, response, new TgResponse(false, "设置失败"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void getSendingBlogs(Context context, TgResultBlock<BlogListInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getSendingBlogs");
        funMap.put("@extra", rtId);
        addTask("getSendingBlogs", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogListInfo listInfo = null;
                try {
                    listInfo = new Gson().fromJson(response, BlogListInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, listInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void resendBlog(Context context,long blogId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "resendBlog");
        funMap.put("blog_id", blogId);
        funMap.put("@extra", rtId);
        addTask("resendBlog", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(isCircleReponseOk(response)){
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "重新发布动态成功"));
                }else{
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "重新发布动态失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void sendBlog(Context context, String text, List<TextEntity> textEntities, List<MediaInfo> mediaInfos, List<Long> mention_ids, List<String> topics, PoiItem choosePoiItem, VisibleTypeInfo visibleTypeInfo, TgResultBlock<TgResponse> resultBlock) {

        if (!getTgData().isValid()) {
            return;
        }

        Map<String, Object> contentMap = new HashMap<>();
        if(!Common.isEmpty(mediaInfos)){
            if(mediaInfos.size()==1&&mediaInfos.get(0).isVideo()){
                Map<String, Object> videoDic = new HashMap<>();
                MediaInfo mediaInfo = mediaInfos.get(0);
                videoDic.put("@type", "inputFileLocal");
                videoDic.put("path", mediaInfo.getMediaPath());
                Map<String, Object> videoWrapper = new HashMap<>();
                videoWrapper.put("@type", "inputBlogVideo");
                videoWrapper.put("file", videoDic);
                videoWrapper.put("duration", mediaInfo.getDuration());
                videoWrapper.put("width", mediaInfo.getWidth());
                videoWrapper.put("height", mediaInfo.getHeight());
                if(!TextUtils.isEmpty(mediaInfo.getThumbnail())){
                    Map<String, Object> innerThumbnailWrapper = new HashMap<>();
                    innerThumbnailWrapper.put("@type","inputFileLocal");
                    innerThumbnailWrapper.put("path",mediaInfo.getThumbnail());
                    Map<String, Object> thumbnailWrapper = new HashMap<>();
                    thumbnailWrapper.put("@type","inputThumbnail");
                    thumbnailWrapper.put("width",mediaInfo.getWidth());
                    thumbnailWrapper.put("height", mediaInfo.getHeight());
                    thumbnailWrapper.put("thumbnail",innerThumbnailWrapper);
                    videoWrapper.put("thumbnail",thumbnailWrapper);
                }
                contentMap.put("@type","inputBlogContentVideo");
                contentMap.put("video",videoWrapper);
            }else{
                List<SubmitWrapperFileInfo> contentInfos = new ArrayList<>();
                for(MediaInfo mediaInfo:mediaInfos){
                    if(!mediaInfo.isVideo()){
                        contentInfos.add(new SubmitWrapperFileInfo("inputBlogPhoto",mediaInfo.getWidth(),mediaInfo.getHeight(),"inputFileLocal",mediaInfo.getMediaPath()));
                    }
                }
                contentMap.put("@type","inputBlogContentPhoto");
                contentMap.put("photos",contentInfos);
            }
        }
        Map<String, Object> locationContentMap = new HashMap<>();
        if(choosePoiItem!=null&&!(choosePoiItem instanceof NotShowPoiItem)){
            Map<String, Object> locationMap = new HashMap<>();
            locationMap.put("latitude",choosePoiItem.getLatLonPoint().getLatitude());
            locationMap.put("longitude",choosePoiItem.getLatLonPoint().getLongitude());
            locationContentMap.put("location",locationMap);
            locationContentMap.put("address",choosePoiItem.getTitle());
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendBlog");
        funMap.put("mention_ids", mention_ids==null?new ArrayList<Long>():mention_ids);
        funMap.put("topics", topics==null?new ArrayList<String>():topics);
        funMap.put("entities",new TextEntities(textEntities));
        funMap.put("text", TextUtils.isEmpty(text)?"":text);
        funMap.put("location", locationContentMap);
        funMap.put("contents",contentMap);
        funMap.put("visible",visibleTypeInfo);
        funMap.put("@extra", rtId);
        addTask("sendBlog", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogInfo blogInfo = null;
                try {
                    blogInfo = new Gson().fromJson(response, BlogInfo.class);
                }catch (Exception e){

                }
                if (blogInfo!=null) {
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.ECircle_Send_Blog_Start,blogInfo));
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "发布动态成功"));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "发布动态失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void createBlogUserGroup(Context context,String title,List<UserInfo> userInfos,TgResultBlock<UserTags> resultBlock) {
        if (!getTgData().isValid()||Common.isEmpty(userInfos)) {
            return;
        }
        List<Long> users = new ArrayList<>();
        for(UserInfo userInfo:userInfos){
            users.add(userInfo.id);
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "createBlogUserGroup");
        funMap.put("title", title);
        funMap.put("users",users);
        funMap.put("@extra", rtId);
        addTask("createBlogUserGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                UserTags userTags = null;
                try {
                    userTags = new Gson().fromJson(response, UserTags.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, userTags);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public boolean editBlogUserGroup(Context context,UserTags preUserTags,UserTags userTags,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()||userTags == null||preUserTags == null) {
            return false;
        }
        if(Common.isEmpty(userTags.users)||Common.isEmpty(preUserTags.users)){
            return false;
        }
        if(userTags.isEqualUsers(preUserTags)){
            if(userTags.isEqualName(preUserTags)){
                return false;
            }
            editBlogUserName(context,userTags.id, userTags.name, resultBlock);
        }else{
            List<Long> preUserIds = preUserTags.users;
            List<Long> currentUserIds = userTags.users;
            List<Long> removeUserIds = new ArrayList<>();
            List<Long> addUserIds = new ArrayList<>();
            for(long userId:preUserIds){
                boolean isFindEqual = false;
                for(long findUserId:currentUserIds){
                    if(userId == findUserId){
                        isFindEqual = true;
                        break;
                    }
                }
                if(!isFindEqual){
                    removeUserIds.add(userId);
                }
            }
            for(long userId:currentUserIds){
                boolean isFindEqual = false;
                for(long findUserId:preUserIds){
                    if(userId == findUserId){
                        isFindEqual = true;
                        break;
                    }
                }
                if(!isFindEqual){
                    addUserIds.add(userId);
                }
            }
            if(!Common.isEmpty(addUserIds)){
                editBlogUserGroupMember(context,userTags.id,true,addUserIds,resultBlock);
            }else if(!Common.isEmpty(removeUserIds)){
                editBlogUserGroupMember(context,userTags.id,false,removeUserIds,resultBlock);
            }else{
                editBlogUserGroupMember(context, userTags.id, true, addUserIds, new TgResultBlock<TgResponse>() {
                    @Override
                    public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {
                        if(obj==null|| !obj.ok){
                            resultBlock.onResult(request,response,obj);
                        }else{
                            editBlogUserGroupMember(context,userTags.id,false,removeUserIds,resultBlock);
                        }
                    }

                    @Override
                    public void onTimeout(Map<String, Object> request) {
                        resultBlock.onTimeout(request);
                    }
                });
            }
        }
        return true;
    }


    public void editBlogUserName(Context context,long groupId,String name,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return ;
        }
        if(TextUtils.isEmpty(name)){
            return ;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("group_id",groupId);
        funMap.put("@type", "editBlogUserGroup");
        funMap.put("title", name);
        funMap.put("@extra", rtId);
        addTask("editBlogUserName", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(isCircleReponseOk(response)){
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "编辑用户分组成功"));
                }else{
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "编辑用户分组失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void deleteBlogUserGroup(Context context,long groupId,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return ;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        List<Long> groups = new ArrayList<>();
        groups.add(groupId);
        funMap.put("groups",groups);
        funMap.put("@type", "deleteBlogUserGroup");
        funMap.put("@extra", rtId);
        addTask("editBlogUserName", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(isCircleReponseOk(response)){
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "删除用户分组成功"));
                }else{
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "删除用户分组失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void editBlogUserGroupMember(Context context,long groupId,boolean isAdd,List<Long> userIds,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return ;
        }
        if(Common.isEmpty(userIds)){
            return ;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("group_id",groupId);
        if(isAdd){
            funMap.put("@type", "addBlogUserGroupMember");
            funMap.put("users",userIds);
        }else{
            funMap.put("@type", "deleteBlogUserGroupMember");
            funMap.put("users",userIds);
        }
        funMap.put("@extra", rtId);
        addTask("editBlogUserGroupMember", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(isCircleReponseOk(response)){
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "编辑用户分组成功"));
                }else{
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "编辑用户分组失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getBlogUserGroups(Context context,TgResultBlock<UserTagListInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getBlogUserGroups");
        funMap.put("@extra", rtId);
        addTask("createBlogUserGroup", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                UserTagListInfo userTags = null;
                try {
                    userTags = new Gson().fromJson(response, UserTagListInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, userTags);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void getBlogReplys(Context context,long blogId,int limit,int offset,TgResultBlock<BlogReplysInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> idMap = new HashMap<>();
        idMap.put("@type","inputBlogIdBlog");
        idMap.put("blog_id",blogId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getBlogReplys");
        funMap.put("id", idMap);
        funMap.put("offset",offset);
        funMap.put("limit",limit);
        funMap.put("@extra", rtId);
        addTask("getBlogReplys", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogReplysInfo replysInfos = null;
                try {
                    replysInfos = new Gson().fromJson(response, BlogReplysInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, replysInfos);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getReplyReplys(Context context,long replyId,int limit,int offset,TgResultBlock<BlogReplysInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> idMap = new HashMap<>();
        idMap.put("@type","inputBlogIdReply");
        idMap.put("reply_id",replyId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getBlogReplys");
        funMap.put("id", idMap);
        funMap.put("offset",offset);
        funMap.put("limit",limit);
        funMap.put("@extra", rtId);
        addTask("getBlogReplys", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogReplysInfo replysInfos = null;
                try {
                    replysInfos = new Gson().fromJson(response, BlogReplysInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, replysInfos);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getBlogUnreads(Context context,int limit,int offset,TgResultBlock<BlogUnreadsInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();

        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getBlogMessages");
        funMap.put("offset",offset);
        funMap.put("limit",limit);
        funMap.put("@extra", rtId);
        addTask("getBlogUnreads", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogUnreadsInfo replysInfos = null;
                try {
                    replysInfos = new Gson().fromJson(response, BlogUnreadsInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, replysInfos);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void clearBlogMessages(Context context,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();

        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "clearBlogMessages");
        funMap.put("@extra", rtId);
        addTask("clearBlogMessages", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(isCircleReponseOk(response)){
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "清除成功"));
                }else{
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "清除失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void getBlogInfo(Context context,long blogId,TgResultBlock<BlogInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        List<Long> ids = new ArrayList<>();
        ids.add(blogId);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getBlogs");
        funMap.put("blog_ids", ids);
        funMap.put("@extra", rtId);
        addTask("getBlogs", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogListInfo blogListInfo = null;
                try {
                    blogListInfo = new Gson().fromJson(response, BlogListInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, (blogListInfo==null||Common.isEmpty(blogListInfo.blogs))?null:blogListInfo.blogs.get(0));
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void commentBlog(Context context, InputBlogIdType idType,String text, TgResultBlock<TgResponse> resultBlock) {
        if(idType==null||TextUtils.isEmpty(text)){
            return;
        }
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "commentBlog");
        funMap.put("id", idType);
        funMap.put("offset",0);
        funMap.put("text", text);
        funMap.put("@extra", rtId);
        addTask("commentBlog", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(isCircleReponseOk(response)){
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "评论成功"));
                }else{
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "评论失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void likeBlog(Context context, InputBlogIdType idType,boolean liked, TgResultBlock<TgResponse> resultBlock) {
        if(idType==null){
            return;
        }
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "likeBlog");
        funMap.put("id", idType);
        funMap.put("liked", liked);
        funMap.put("@extra", rtId);
        addTask("likeBlog", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(isCircleReponseOk(response)){
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "点赞成功"));
                }else{
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "点赞失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void followBlog(Context context, long user_id,boolean followed, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "followBlog");
        funMap.put("user_id", user_id);
        funMap.put("followed", followed);
        funMap.put("@extra", rtId);
        addTask("followBlog", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(isCircleReponseOk(response)){
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "关注成功"));
                }else{
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "关注失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void getBlogUser(Context context,long userId,TgResultBlock<BlogUserInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getBlogUser");
        funMap.put("user_id", userId);
        funMap.put("@extra", rtId);
        addTask("getBlogUser", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogUserInfo blogUserInfo = null;
                try {
                    blogUserInfo = new Gson().fromJson(response, BlogUserInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response,blogUserInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void deleteBlog(Context context, long blog_id, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        List<Long> list = new ArrayList<>();
        list.add(blog_id);
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "deleteBlog");
        funMap.put("blog_ids", list);
        funMap.put("@extra", rtId);
        addTask("deleteBlog", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(isCircleReponseOk(response)){
                    resultBlock.onResult(request, response, new TgResponse(true, 200, "屏蔽动态成功"));
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_Delete_Blog,blog_id));
                }else{
                    resultBlock.onResult(request, response, new TgResponse(false, 201, "屏蔽动态失败，请稍后重试"));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }
    public int mCircleUnreadCount = 0;

    public void getCircleUnreadCount() {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getUnreadCount");
        funMap.put("@extra", rtId);
        addTask("getUnreadCount", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                int count = 0;
                try {
                    count = response.get("count").getAsInt();
                }catch (Exception e){

                }
                if(mCircleUnreadCount!=count){
                    mCircleUnreadCount = count;
                    EventBus.getDefault().post(TgEvent.event(EUser_TgEvent.EUser_Td_update_Circle_Unread_count,mCircleUnreadCount));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {

            }
        });
    }


    public void getBlogFollows(Context context,long userId,int limit,int offset,TgResultBlock<BlogLikeInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getBlogFollows");
        funMap.put("offset",offset);
        funMap.put("limit",limit);
        funMap.put("user_id", userId);
        funMap.put("@extra", rtId);
        addTask("getBlogFollows", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogLikeInfo blogLikeInfo = null;
                try {
                    blogLikeInfo = new Gson().fromJson(response, BlogLikeInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, blogLikeInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getBlogFans(Context context,long userId,int limit,int offset,TgResultBlock<BlogLikeInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getBlogFans");
        funMap.put("offset",offset);
        funMap.put("limit",limit);
        funMap.put("user_id", userId);
        funMap.put("@extra", rtId);
        addTask("getBlogFans", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogLikeInfo blogLikeInfo = null;
                try {
                    blogLikeInfo = new Gson().fromJson(response, BlogLikeInfo.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, blogLikeInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void getHotTopic(Context context,int limit,TgResultBlock<List<CircleTopicInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getHotTopic");
        funMap.put("limit",limit);
        funMap.put("@extra", rtId);
        addTask("getHotTopic", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogTopics blogTopics = null;
                try {
                    blogTopics = new Gson().fromJson(response, BlogTopics.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, blogTopics==null?null:blogTopics.topics);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void searchTopic(Context context,String keyword,TgResultBlock<List<CircleTopicInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "searchTopic");
        funMap.put("keyword",keyword);
        funMap.put("@extra", rtId);
        addTask("searchTopic", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                BlogTopics blogTopics = null;
                try {
                    blogTopics = new Gson().fromJson(response, BlogTopics.class);
                }catch (Exception e){

                }
                resultBlock.onResult(request, response, blogTopics==null?null:blogTopics.topics);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    private boolean isCircleReponseOk(JsonObject response){
        try {
            return "ok".equals(response.get("@type").getAsString());
        }catch (Exception e){
            return false;
        }
    }


    public void getActiveSessions(Context context, TgResultBlock<TotalSessionsInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getActiveSessions");
        funMap.put("@extra", rtId);
        addTask("getActiveSessions", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                TotalSessionsInfo listInfo = null;
                listInfo = new Gson().fromJson(response, TotalSessionsInfo.class);
                resultBlock.onResult(request, response, listInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void terminateAllOtherSessions(Context context, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "terminateAllOtherSessions");
        funMap.put("@extra", rtId);
        addTask("terminateAllOtherSessions", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void terminateSession(Context context, long session_id,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "terminateSession");
        funMap.put("session_id", session_id);
        funMap.put("@extra", rtId);
        addTask("terminateSession", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void setAccountTtl(Context context, AccountTtlInfo ttlInfo, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "setAccountTtl");
        funMap.put("ttl", ttlInfo);
        funMap.put("@extra", rtId);
        addTask("setAccountTtl", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getAccountTtl(Context context, TgResultBlock<AccountTtlInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "getAccountTtl");
        funMap.put("@extra", rtId);
        addTask("getAccountTtl", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                AccountTtlInfo listInfo = new Gson().fromJson(response, AccountTtlInfo.class);
                resultBlock.onResult(request, response, listInfo);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void toggleMultiOnline(Context context, boolean isMultiOnline, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("isOn", isMultiOnline);
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "accounts.toggleMultiOnline");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("accounts.toggleMultiOnline", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, ""));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void getMultiOnline(Context context,  TgResultBlock<Boolean> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "accounts.getMultiOnline");
        funMap.put("@extra", rtId);
        addTask("queryRedHistoryCall", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if(context!=null){
                    if (isActivityDestroy(context)) return;
                }
                JsonObject data = customResultData(response);
                boolean isMultiOnline = true;
                if(data!=null&&data.has("isOn")){
                    isMultiOnline = data.get("isOn").getAsBoolean();
                }
                resultBlock.onResult(request, response, isMultiOnline);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if(context!=null) {
                    if (isActivityDestroy(context)) return;
                }
                resultBlock.onTimeout(request);
            }
        });
    }


    public void deleteAccount(Context context, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "deleteAccount");
        funMap.put("@extra", rtId);
        addTask("deleteAccount", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, errorMsg(response)));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void kickWhoSendKeyword(Context context, long chatId, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "chats.kickWhoSendKeyword");
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("chats.kickWhoSendKeyword", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, ""));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }

    public void modifyNotificationSettings(Context context, NotificationSettingsInfo settingsInfo, TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "accounts.modifyNotificationSettings");
        funMap.put("parameters", new Gson().toJson(settingsInfo));
        funMap.put("@extra", rtId);
        addTask("accounts.modifyNotificationSettings", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, ""));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    public void getNotificationSettings(Context context,  TgResultBlock<NotificationSettingsInfo> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "accounts.getNotificationSettings");
        funMap.put("@extra", rtId);
        addTask("accounts.getNotificationSettings", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if(context!=null){
                    if (isActivityDestroy(context)) return;
                }
                JsonObject data = customResultData(response);
                resultBlock.onResult(request, response, GsonUtils.fromJson(data.toString(),NotificationSettingsInfo.class));
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if(context!=null) {
                    if (isActivityDestroy(context)) return;
                }
                resultBlock.onTimeout(request);
            }
        });
    }



    public void setGroupNickName(Context context, long chatId,String nickName,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "chats.setNickname");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        parameters.put("nickname", nickName);
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("chats.setNickname", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, ""));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                resultBlock.onTimeout(request);
            }
        });
    }


    //chatType  1单聊  2群聊
    public void sendReaction(Context context,long chatId,int chatType, long messageId,int reactionId,TgResultBlock<TgResponse> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        funMap.put("method", "messages.sendReaction");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("messageId",messageId );
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        parameters.put("type", chatType);
        parameters.put("reactionId", reactionId);
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("@extra", rtId);
        addTask("messages.sendReaction", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if (isActivityDestroy(context)) return;
                if(resultBlock==null) return;
                if (isResultError(response)) {
                    resultBlock.onResult(request, response, new TgResponse(false, ""));
                } else {
                    resultBlock.onResult(request, response, new TgResponse(true, ""));
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if (isActivityDestroy(context)) return;
                if(resultBlock==null) return;
                resultBlock.onTimeout(request);
            }
        });
    }



    public void getMessagesReactions(Context context,long chatId,int chatType,List<Long> messageIds,  TgResultBlock<List<MessageReactionInfo>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("messageIds",messageIds );
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        parameters.put("type", chatType);
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("method", "messages.getMessagesReactions");
        funMap.put("@extra", rtId);
        addTask("messages.getMessagesReactions", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if(context!=null){
                    if (isActivityDestroy(context)) return;
                }
                JsonArray data = customResultListData(response,true);
                List<MessageReactionInfo> reactionInfos = data!=null?GsonUtils.fromJson(data.toString(),new TypeToken<List<MessageReactionInfo>>() {}.getType()):null;
                resultBlock.onResult(request, response, reactionInfos);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if(context!=null) {
                    if (isActivityDestroy(context)) return;
                }
                resultBlock.onTimeout(request);
            }
        });
    }


    public void getMessagesReaction(Context context,long chatId,int chatType,Long messageId,  TgResultBlock<List<MessageReaction>> resultBlock) {
        if (!getTgData().isValid()) {
            return;
        }
        //准备请求报文
        int rtId = getTgData().getNextRequestId();
        Map<String, Object> funMap = new HashMap<>();
        funMap.put("@type", "sendCustomRequest");
        Map<String, Object> parameters = new HashMap<>();
        List<Long> messageIds = new ArrayList<>();
        messageIds.add(messageId);
        parameters.put("messageIds",messageIds );
        parameters.put("chatId", ChatInfo.toServerPeerId(chatId));
        parameters.put("type", chatType);
        funMap.put("parameters", new Gson().toJson(parameters));
        funMap.put("method", "messages.getMessagesReactions");
        funMap.put("@extra", rtId);
        addTask("messages.getMessagesReactions", rtId, funMap, new TgResultBlock<Object>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, Object obj) {
                if(context!=null){
                    if (isActivityDestroy(context)) return;
                }
                JsonArray data = customResultListData(response,true);
                List<MessageReactionInfo> reactionInfos = data!=null?GsonUtils.fromJson(data.toString(),new TypeToken<List<MessageReactionInfo>>() {}.getType()):null;
                List<MessageReaction> reactions = null;
                if(!Common.isEmpty(reactionInfos)){
                    List<MessageReaction> messageReactions = reactionInfos.get(0).reactionList;
                    if(!Common.isEmpty(messageReactions)){
                        reactions = new ArrayList<>();
                        for(MessageReaction reaction:messageReactions){
                            int index = reactions.indexOf(reaction);
                            if(index!=-1){
                                reactions.get(index).appendUserId(reaction.userId);
                            }else{
                                reaction.appendUserId(reaction.userId);
                                reactions.add(reaction);
                            }
                        }
                    }
                }
                resultBlock.onResult(request, response, reactions);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                if(context!=null) {
                    if (isActivityDestroy(context)) return;
                }
                resultBlock.onTimeout(request);
            }
        });
    }


}